]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
Salome HOME
Make v1.1.0 compilable under linux
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_ConstraintMirror.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:    SketchPlugin_ConstraintMirror.cpp
4 // Created: 17 Mar 2015
5 // Author:  Artem ZHIDKOV
6
7 #include "SketchPlugin_ConstraintMirror.h"
8
9 #include <ModelAPI_AttributeDouble.h>
10 #include <ModelAPI_Data.h>
11 #include <ModelAPI_ResultConstruction.h>
12 #include <ModelAPI_AttributeRefList.h>
13 #include <ModelAPI_AttributeSelectionList.h>
14 #include <ModelAPI_Session.h>
15 #include <ModelAPI_Validator.h>
16
17 #include <SketchPlugin_Line.h>
18 #include <SketchPlugin_Sketch.h>
19
20 #include <SketcherPrs_Factory.h>
21
22 #include <Config_PropManager.h>
23
24 SketchPlugin_ConstraintMirror::SketchPlugin_ConstraintMirror()
25 {
26 }
27
28 void SketchPlugin_ConstraintMirror::initAttributes()
29 {
30   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
31   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
32   data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId());
33   AttributeSelectionListPtr aSelection = 
34     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
35     SketchPlugin_ConstraintMirror::MIRROR_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
36   aSelection->setSelectionType("EDGE");
37   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B());
38   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_C());
39 }
40
41 void SketchPlugin_ConstraintMirror::execute()
42 {
43   AttributeSelectionListPtr aMirrorObjectRefs =
44       selectionList(SketchPlugin_ConstraintMirror::MIRROR_LIST_ID());
45   if (!aMirrorObjectRefs->isInitialized())
46     return;
47
48   std::shared_ptr<ModelAPI_Data> aData = data();
49   AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
50       aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
51   AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
52       aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
53   std::list<ObjectPtr> anInitialList =  aRefListOfShapes->list();
54   std::list<ObjectPtr> aMirroredList =  aRefListOfMirrored->list();
55   std::vector<bool> isUsed(anInitialList.size(), false);
56   // add new items to the list
57   for(int anInd = 0; anInd < aMirrorObjectRefs->size(); anInd++) {
58     std::shared_ptr<ModelAPI_AttributeSelection> aSelect = aMirrorObjectRefs->value(anInd);
59     std::list<ObjectPtr>::const_iterator anIt = anInitialList.begin();
60     std::vector<bool>::iterator aUsedIt = isUsed.begin();
61     for (; anIt != anInitialList.end(); anIt++, aUsedIt++)
62       if (*anIt == aSelect->context()) {
63         *aUsedIt = true;
64         break;
65       }
66     if (anIt == anInitialList.end())
67       aRefListOfShapes->append(aSelect->context());
68   }
69   // remove unused items
70   std::list<ObjectPtr>::iterator anInitIter = anInitialList.begin();
71   std::list<ObjectPtr>::iterator aMirrorIter = aMirroredList.begin();
72   std::vector<bool>::iterator aUsedIter = isUsed.begin();
73   for (; aUsedIter != isUsed.end(); aUsedIter++) {
74     if (!(*aUsedIter)) {
75       aRefListOfShapes->remove(*anInitIter);
76       if (aMirrorIter != aMirroredList.end()) {
77         aRefListOfMirrored->remove(*aMirrorIter);
78         // remove the corresponding feature from the sketch
79         ResultConstructionPtr aRC =
80             std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aMirrorIter);
81         DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
82         FeaturePtr aFeature =  aDoc ? aDoc->feature(aRC) : FeaturePtr();
83         if (aFeature)
84           aDoc->removeFeature(aFeature);
85       }
86     }
87     if (anInitIter != anInitialList.end())
88       anInitIter++;
89     if (aMirrorIter != aMirroredList.end())
90       aMirrorIter++;
91   }
92
93   // Check consistency of initial list and mirrored list
94   anInitialList =  aRefListOfShapes->list();
95   anInitIter = anInitialList.begin();
96   aMirrorIter = aMirroredList.begin();
97   int indFirstWrong = 0; // index of element starts difference in the lists
98   std::set<int> anInvalidInd; // list of indices of removed features
99   std::shared_ptr<SketchPlugin_Feature> aFeatureIn, aFeatureOut;
100   for ( ; anInitIter != anInitialList.end(); anInitIter++, indFirstWrong++) {
101     // Add features and store indices of objects to remove
102     aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
103     ResultConstructionPtr aRCIn;
104     if (!aFeatureIn) {
105       aRCIn = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*anInitIter);
106       if (aRCIn)
107         aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(
108             aRCIn->document()->feature(aRCIn));
109     }
110     if (aMirrorIter == aMirroredList.end())
111       aFeatureOut = std::shared_ptr<SketchPlugin_Feature>();
112     else {
113       aFeatureOut = std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirrorIter);
114       if (!aFeatureOut) {
115         ResultConstructionPtr aRC =
116             std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*anInitIter);
117         if (aRC)
118           aFeatureOut = std::dynamic_pointer_cast<SketchPlugin_Feature>(
119               aRC->document()->feature(aRC));
120       }
121     }
122     if (!aFeatureIn) {
123       if (aFeatureOut)
124         break; // the lists are inconsistent
125       continue;
126     }
127     if (!aFeatureOut) {
128       if (aMirrorIter != aMirroredList.end())
129         break; // the lists are inconsistent
130       // There is no mirrored object yet, create it
131       FeaturePtr aNewFeature = sketch()->addFeature(aFeatureIn->getKind());
132       aFeatureIn->data()->copyTo(aNewFeature->data());
133       aNewFeature->execute();
134
135       std::shared_ptr<GeomAPI_Shape> aShapeIn = aRCIn->shape();
136       const std::list<ResultPtr>& aResults = aNewFeature->results();
137       std::list<ResultPtr>::const_iterator anIt = aResults.begin();
138       for (; anIt != aResults.end(); anIt++) {
139         ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*anIt);
140         if (!aRC) continue;
141         std::shared_ptr<GeomAPI_Shape> aShapeOut = aRC->shape();
142         if ((aShapeIn->isVertex() && aShapeOut->isVertex()) ||
143             (aShapeIn->isEdge() && aShapeOut->isEdge()) ||
144             (aShapeIn->isFace() && aShapeOut->isFace()))
145           aRefListOfMirrored->append(aRC);
146       }
147       continue;
148     }
149     if (aFeatureIn->getKind() != aFeatureOut->getKind())
150       break; // the lists are inconsistent
151     if (!aFeatureIn->data()->isValid()) {
152       // initial feature was removed, delete it from lists
153       anInvalidInd.insert(indFirstWrong);
154     }
155     aMirrorIter++;
156   }
157   // Remove from the list objects already deleted before
158   std::set<int>::reverse_iterator anIt = anInvalidInd.rbegin();
159   for ( ; anIt != anInvalidInd.rend(); anIt++) {
160     if (*anIt < indFirstWrong) indFirstWrong--;
161     aRefListOfShapes->remove(aRefListOfShapes->object(*anIt));
162     aRefListOfMirrored->remove(aRefListOfMirrored->object(*anIt));
163   }
164   // If the lists inconsistent, remove all objects from mirrored list starting from indFirstWrong
165   if (anInitIter != anInitialList.end()) {
166     while (aRefListOfMirrored->size() > indFirstWrong)
167       aRefListOfMirrored->remove(aRefListOfMirrored->object(indFirstWrong));
168     // Create mirrored features instead of removed
169     anInitialList =  aRefListOfShapes->list();
170     anInitIter = anInitialList.begin();
171     for (int i = 0; i < indFirstWrong; i++) anInitIter++;
172     for ( ; anInitIter != anInitialList.end(); anInitIter++) {
173       aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
174       FeaturePtr aNewFeature = aFeatureIn->document()->addFeature(aFeatureIn->getKind());
175       aRefListOfMirrored->append(aNewFeature);
176     }
177   }
178 }
179
180 AISObjectPtr SketchPlugin_ConstraintMirror::getAISObject(AISObjectPtr thePrevious)
181 {
182   if (!sketch())
183     return thePrevious;
184
185   AISObjectPtr anAIS = thePrevious;
186   /// TODO: Equal constraint presentation should be put here
187   return anAIS;
188 }
189
190