1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: SketchPlugin_MultiTranslation.cpp
4 // Created: 21 Apr 2015
5 // Author: Artem ZHIDKOV
7 #include "SketchPlugin_MultiTranslation.h"
8 #include "SketchPlugin_Tools.h"
10 #include <GeomAPI_XY.h>
11 #include <GeomDataAPI_Point2D.h>
12 #include <ModelAPI_AttributeDouble.h>
13 #include <ModelAPI_AttributeInteger.h>
14 #include <ModelAPI_Data.h>
15 #include <ModelAPI_ResultConstruction.h>
16 #include <ModelAPI_AttributeRefList.h>
17 #include <ModelAPI_AttributeRefAttr.h>
18 #include <ModelAPI_AttributeString.h>
19 #include <ModelAPI_Events.h>
20 #include <ModelAPI_Session.h>
21 #include <ModelAPI_Validator.h>
22 #include <ModelAPI_Tools.h>
24 #include <SketchPlugin_SketchEntity.h>
25 #include <SketcherPrs_Factory.h>
27 SketchPlugin_MultiTranslation::SketchPlugin_MultiTranslation()
31 void SketchPlugin_MultiTranslation::initAttributes()
33 data()->addAttribute(VALUE_TYPE(), ModelAPI_AttributeString::typeId());
35 data()->addAttribute(START_POINT_ID(), ModelAPI_AttributeRefAttr::typeId());
36 data()->addAttribute(END_POINT_ID(), ModelAPI_AttributeRefAttr::typeId());
38 data()->addAttribute(NUMBER_OF_OBJECTS_ID(), ModelAPI_AttributeInteger::typeId());
39 data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefList::typeId());
40 data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
41 data()->addAttribute(TRANSLATION_LIST_ID(), ModelAPI_AttributeRefList::typeId());
42 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_A());
43 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B());
46 void SketchPlugin_MultiTranslation::execute()
49 // it is possible, that this method is called before this feature has back reference to sketch
50 // in this case, the execute is performed after this is done
54 AttributeRefListPtr aTranslationObjectRefs = reflist(TRANSLATION_LIST_ID());
55 int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value()-1;
59 // Calculate shift vector
60 AttributeRefAttrPtr aStartAttr = data()->refattr(START_POINT_ID());
61 AttributeRefAttrPtr anEndAttr = data()->refattr(END_POINT_ID());
63 if (!aStartAttr || !anEndAttr || !aStartAttr->isInitialized() || !anEndAttr->isInitialized())
66 DataPtr aData = data();
67 AttributePoint2DPtr aStart = GeomDataAPI_Point2D::getPoint2D(aData, START_POINT_ID());
68 AttributePoint2DPtr aEnd = GeomDataAPI_Point2D::getPoint2D(aData, END_POINT_ID());
72 std::shared_ptr<GeomAPI_XY> aShiftVec(new GeomAPI_XY(aEnd->x() - aStart->x(), aEnd->y() - aStart->y()));
74 // Wait all objects being created, then send update events
75 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
76 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
78 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
80 AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
81 aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
82 AttributeRefListPtr aRefListOfTranslated = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
83 aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
84 int aCurrentNbCopies = aRefListOfShapes->size() ?
85 aRefListOfTranslated->size() / aRefListOfShapes->size() - 1 : 0;
86 std::list<ObjectPtr> anInitialList = aRefListOfShapes->list();
87 std::list<ObjectPtr> aTargetList = aRefListOfTranslated->list();
88 std::list<ObjectPtr> anAddition;
89 std::vector<bool> isUsed(anInitialList.size(), false);
90 // collect new items and check the items to remove
91 for(int anInd = 0; anInd < aTranslationObjectRefs->size(); anInd++) {
92 //std::shared_ptr<ModelAPI_AttributeSelection> aSelect = aTranslationObjectRefs->value(anInd);
93 ObjectPtr anObject = aTranslationObjectRefs->object(anInd);
94 std::list<ObjectPtr>::const_iterator anIt = anInitialList.begin();
95 std::vector<bool>::iterator aUsedIt = isUsed.begin();
96 for (; anIt != anInitialList.end(); anIt++, aUsedIt++)
97 if (*anIt == anObject) {
101 if (anIt == anInitialList.end())
102 anAddition.push_back(anObject);
104 // remove unused items
105 std::list<ObjectPtr>::iterator anInitIter = anInitialList.begin();
106 std::list<ObjectPtr>::iterator aTargetIter = aTargetList.begin();
107 std::vector<bool>::iterator aUsedIter = isUsed.begin();
108 std::set<FeaturePtr> aFeaturesToBeRemoved;
109 for (; aUsedIter != isUsed.end(); aUsedIter++) {
111 aRefListOfShapes->remove(*anInitIter);
112 aRefListOfTranslated->remove(*aTargetIter++);
113 for (int i = 0; i < aCurrentNbCopies && aTargetIter != aTargetList.end(); i++, aTargetIter++) {
114 aRefListOfTranslated->remove(*aTargetIter);
115 // remove the corresponding feature from the sketch
116 ResultConstructionPtr aRC =
117 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aTargetIter);
118 DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
119 FeaturePtr aFeature = aDoc ? aDoc->feature(aRC) : FeaturePtr();
121 aFeaturesToBeRemoved.insert(aFeature);
124 for (int i = 0; i <= aNbCopies && aTargetIter != aTargetList.end(); i++)
127 if (anInitIter != anInitialList.end())
130 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
131 // change number of copies
132 if (aCurrentNbCopies != 0 && aNbCopies != aCurrentNbCopies) {
133 bool isAdd = aNbCopies > aCurrentNbCopies;
134 int aMinCopies = isAdd ? aCurrentNbCopies : aNbCopies;
135 int aMaxCopies = isAdd ? aNbCopies : aCurrentNbCopies;
138 aTargetList = aRefListOfTranslated->list();
139 aTargetIter = aTargetList.begin();
140 ObjectPtr anObjToCopy = *aTargetIter;
141 while (aTargetIter != aTargetList.end()) {
142 aRefListOfTranslated->remove(*aTargetIter);
145 if (ind > aMinCopies && ind <=aMaxCopies) {
146 while (ind <= aMaxCopies) {
148 // Add new shifted item
149 ObjectPtr anObject = copyFeature(anObjToCopy);
150 aTargetList.insert(aTargetIter, anObject);
153 std::list<ObjectPtr>::iterator aRemoveIt = aTargetIter++;
154 ObjectPtr anObject = *aRemoveIt;
155 aTargetList.erase(aRemoveIt);
156 aRefListOfTranslated->remove(anObject);
157 // remove the corresponding feature from the sketch
158 ResultConstructionPtr aRC =
159 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(anObject);
160 DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
161 FeaturePtr aFeature = aDoc ? aDoc->feature(aRC) : FeaturePtr();
163 aDoc->removeFeature(aFeature);
168 if (aTargetIter != aTargetList.end())
169 anObjToCopy = *aTargetIter;
173 for (aTargetIter = aTargetList.begin(); aTargetIter != aTargetList.end(); aTargetIter++)
174 aRefListOfTranslated->append(*aTargetIter);
177 std::list<ObjectPtr>::iterator anAddIter = anAddition.begin();
178 for (; anAddIter != anAddition.end(); anAddIter++) {
179 aRefListOfShapes->append(*anAddIter);
180 aRefListOfTranslated->append(*anAddIter);
181 for (int i = 0; i < aNbCopies; i++) {
182 ObjectPtr anObject = copyFeature(*anAddIter);
183 aRefListOfTranslated->append(anObject);
187 // send events to update the sub-features by the solver
189 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
192 AISObjectPtr SketchPlugin_MultiTranslation::getAISObject(AISObjectPtr thePrevious)
197 AISObjectPtr anAIS = SketcherPrs_Factory::translateConstraint(this, sketch()->coordinatePlane(),
202 void SketchPlugin_MultiTranslation::erase()
204 static Events_Loop* aLoop = Events_Loop::loop();
205 static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
207 // Set copy attribute to false on all copied features.
208 AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
209 data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
210 AttributeRefListPtr aRefListOfTranslated = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
211 data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
213 if(aRefListOfShapes.get() && aRefListOfTranslated.get()) {
214 for(int anIndex = 0; anIndex < aRefListOfTranslated->size(); anIndex++) {
215 ObjectPtr anObject = aRefListOfTranslated->object(anIndex);
216 if(aRefListOfShapes->isInList(anObject)) {
217 // Don't modify attribute of original features, just skip.
221 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
223 FeaturePtr aFeature = aRes->document()->feature(aRes);
225 AttributeBooleanPtr aBooleanAttr = aFeature->boolean(SketchPlugin_SketchEntity::COPY_ID());
226 if(aBooleanAttr.get()) {
227 if (ModelAPI_Session::get()->isOperation()) // if this is not undo or redo
228 aBooleanAttr->setValue(false);
229 // Redisplay object as it is not copy anymore.
230 ModelAPI_EventCreator::get()->sendUpdated(aRes, aRedispEvent);
238 SketchPlugin_ConstraintBase::erase();
241 ObjectPtr SketchPlugin_MultiTranslation::copyFeature(ObjectPtr theObject)
243 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theObject);
244 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
245 if (!aFeature || !aResult)
248 FeaturePtr aNewFeature = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(aFeature, sketch(), true);
250 aNewFeature->execute();
251 static Events_ID aRedisplayEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
252 ModelAPI_EventCreator::get()->sendUpdated(aNewFeature, aRedisplayEvent);
254 std::shared_ptr<GeomAPI_Shape> aShapeIn = aResult->shape();
255 const std::list<ResultPtr>& aResults = aNewFeature->results();
256 std::list<ResultPtr>::const_iterator anIt = aResults.begin();
257 for (; anIt != aResults.end(); anIt++) {
258 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*anIt);
260 std::shared_ptr<GeomAPI_Shape> aShapeOut = aRC->shape();
261 if ((aShapeIn->isVertex() && aShapeOut->isVertex()) ||
262 (aShapeIn->isEdge() && aShapeOut->isEdge()) ||
263 (aShapeIn->isFace() && aShapeOut->isFace()))
269 void SketchPlugin_MultiTranslation::attributeChanged(const std::string& theID)
271 if (theID == TRANSLATION_LIST_ID()) {
272 AttributeRefListPtr aTranslationObjectRefs = reflist(TRANSLATION_LIST_ID());
273 if (aTranslationObjectRefs->size() == 0) {
274 int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value()-1;
277 // Clear list of objects
278 AttributeRefListPtr aRefListOfTranslated = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
279 data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
280 std::list<ObjectPtr> aTargetList = aRefListOfTranslated->list();
281 std::list<ObjectPtr>::iterator aTargetIter = aTargetList.begin();
282 while (aTargetIter != aTargetList.end()) {
284 for (int i = 0; i < aNbCopies && aTargetIter != aTargetList.end(); i++, aTargetIter++) {
285 aRefListOfTranslated->remove(*aTargetIter);
286 // remove the corresponding feature from the sketch
287 ResultConstructionPtr aRC =
288 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aTargetIter);
289 DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
290 FeaturePtr aFeature = aDoc ? aDoc->feature(aRC) : FeaturePtr();
292 aDoc->removeFeature(aFeature);
295 aRefListOfTranslated->clear();
296 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
297 data()->attribute(SketchPlugin_Constraint::ENTITY_A()))->clear();
298 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
299 data()->attribute(SketchPlugin_Constraint::ENTITY_B()))->clear();