1 // Copyright (C) 2017-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "FeaturesPlugin_Copy.h"
22 #include <ModelAPI_AttributeSelectionList.h>
23 #include <ModelAPI_AttributeInteger.h>
24 #include <ModelAPI_Tools.h>
26 #include <GeomAlgoAPI_Copy.h>
27 #include <GeomAlgoAPI_Tools.h>
28 #include <GeomAPI_ShapeExplorer.h>
32 void FeaturesPlugin_Copy::initAttributes()
34 data()->addAttribute(OBJECTS(), ModelAPI_AttributeSelectionList::typeId());
35 data()->addAttribute(NUMBER(), ModelAPI_AttributeInteger::typeId());
38 static GeomShapePtr shapeOfSelection(AttributeSelectionPtr theSel) {
40 FeaturePtr aSelFeature = theSel->contextFeature();
41 if (aSelFeature.get()) {
42 if (aSelFeature->results().empty()) // if selected feature has no results, make nothing
44 if (aSelFeature->results().size() == 1) { // for one sub-result don't make compound
45 aResult = aSelFeature->firstResult()->shape();
49 aResult = theSel->value();
51 if (theSel->context().get())
52 aResult = theSel->context()->shape();
57 void FeaturesPlugin_Copy::execute()
59 int aCopiesNum = integer(NUMBER())->value();
60 AttributeSelectionListPtr aList = selectionList(OBJECTS());
62 std::set<std::wstring> anExistingNames; // to avoid names duplication
63 for(int aCopy = 0; aCopy < aCopiesNum; aCopy++) {
64 for (int aSelIndex = 0; aSelIndex < aList->size(); aSelIndex++) {
65 AttributeSelectionPtr aSel = aList->value(aSelIndex);
66 GeomShapePtr aShape = shapeOfSelection(aSel);
69 std::shared_ptr<GeomAlgoAPI_Copy> aCopyBuilder(new GeomAlgoAPI_Copy(aShape, false, false));
71 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aCopyBuilder, getKind(), anError)) {
75 GeomShapePtr aResult = aCopyBuilder->shape();
77 std::wstring aBaseName = aSel->context() ? aSel->context()->data()->name() :
78 aSel->contextFeature()->firstResult()->data()->name();
83 std::wostringstream aNameStr;
84 aNameStr << aBaseName << "_" << (aCopy + anInd);
85 aName = aNameStr.str();
86 } while (anExistingNames.count(aName));
87 anExistingNames.insert(aName);
89 std::shared_ptr<ModelAPI_ResultBody> aResultBody =
90 document()->createBody(data(), aResultIndex);
91 aResultBody->data()->setName(aName);
92 // to make sub-results also names with a similar name temporarily rename the feature
93 std::wstring anOrigName = name();
94 data()->setName(aBaseName);
95 aResultBody->store(aResult);
96 data()->setName(anOrigName);
97 aResultBody->loadFirstLevel(aResult, "Copy");
98 setResult(aResultBody, aResultIndex++);
101 removeResults(aResultIndex);
104 void FeaturesPlugin_Copy::getCopies(
105 ObjectPtr theContext, std::shared_ptr<GeomAPI_Shape> theValue,
106 std::list<ObjectPtr>& theCopyContext, std::list<std::shared_ptr<GeomAPI_Shape> >& theCopyVals)
108 ResultPtr aContextRes = std::dynamic_pointer_cast<ModelAPI_Result>(theContext);
109 GeomShapePtr aGroupValue = theValue.get() ? theValue : aContextRes->shape();
111 AttributeSelectionListPtr aList = selectionList(OBJECTS());
112 std::list<ResultPtr>::const_iterator aResIter = results().cbegin();
113 while(aResIter != results().cend()) { // do as long as many iterations
114 for (int aSelIndex = 0; aSelIndex < aList->size(); aSelIndex++) {
115 if (aResIter == results().cend()) // no more results corresponding to the selection
117 AttributeSelectionPtr aSel = aList->value(aSelIndex);
118 GeomShapePtr aShape = shapeOfSelection(aSel);
122 if (aShape->isSubShape(aGroupValue, false)) { // group value is subshape of copied => copy
123 // search the same result in the copy by the same index of sub-shape in the shape
124 GeomAPI_ShapeExplorer anOrigExp(aShape, aGroupValue->shapeType());
125 GeomAPI_ShapeExplorer aCopyShape((*aResIter)->shape(), aGroupValue->shapeType());
126 for(; anOrigExp.more(); anOrigExp.next(), aCopyShape.next()) {
127 if (anOrigExp.current()->isSame(aGroupValue)) {
128 // searching for sub-result if it is composite result, but context-not
129 ResultPtr aResContext = *aResIter;
130 if (aContextRes->shape()->shapeType() > (*aResIter)->shape()->shapeType()) {
131 ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResContext);
132 if (aResBody.get()) {
133 std::list<ResultPtr> aSubs;
134 ModelAPI_Tools::allSubs(aResBody, aSubs, true);
135 std::list<ResultPtr>::iterator aSubIter = aSubs.begin();
136 for(; aSubIter != aSubs.end(); aSubIter++) {
137 GeomShapePtr aSubShape = (*aSubIter)->shape();
138 if (aSubShape.get() && aSubShape->isSubShape(aCopyShape.current(), false)) {
139 aResContext = *aSubIter;
145 theCopyContext.push_back(aResContext);
146 theCopyVals.push_back(aResContext->shape()->isSame(
147 aCopyShape.current()) ? GeomShapePtr() : aCopyShape.current());