Salome HOME
Issue #1649: Added options to create plane by coincident point;
[modules/shaper.git] / src / InitializationPlugin / InitializationPlugin_Plugin.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 #include <InitializationPlugin_Plugin.h>
4
5 #include <ModelAPI_Session.h>
6 #include <ModelAPI_Document.h>
7 #include <ModelAPI_AttributeDouble.h>
8 #include <ModelAPI_AttributeString.h>
9 #include <ModelAPI_AttributeSelection.h>
10 #include <ModelAPI_Events.h>
11 #include <ModelAPI_Result.h>
12
13 #include <Events_Message.h>
14 #include <Events_InfoMessage.h>
15
16 #include <memory>
17
18 #define NESTED_TOOLBOX_FIX
19
20 // the only created instance of this plugin
21 static InitializationPlugin_Plugin* MY_INITIALIZATIONPLUGIN_INSTANCE =
22     new InitializationPlugin_Plugin();
23
24 InitializationPlugin_Plugin::InitializationPlugin_Plugin()
25 {
26   Events_Loop* aLoop = Events_Loop::loop();
27   const Events_ID kDocCreatedEvent = ModelAPI_DocumentCreatedMessage::eventId();
28   aLoop->registerListener(this, kDocCreatedEvent, NULL, true);
29 }
30
31 void InitializationPlugin_Plugin::processEvent(const std::shared_ptr<Events_Message>& theMessage)
32 {
33   const Events_ID kDocCreatedEvent = ModelAPI_DocumentCreatedMessage::eventId();
34   if (theMessage->eventID() == kDocCreatedEvent) {
35     std::shared_ptr<ModelAPI_DocumentCreatedMessage> aMessage = std::dynamic_pointer_cast<
36         ModelAPI_DocumentCreatedMessage>(theMessage);
37     DocumentPtr aDoc = aMessage->document();
38
39     /// Issue 431: for the current moment create planes only in the module document,
40     /// Later if it is needed we may create special initial planes in Parts (may be different)
41     if (aDoc != ModelAPI_Session::get()->moduleDocument())
42       return;
43
44     std::list<FeaturePtr> aFeatures;
45
46     // the viewer update should be blocked in order to avoid the features blinking before they are
47     // hidden
48     std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
49         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
50     Events_Loop::loop()->send(aMsg);
51
52     FeaturePtr aOrigin = createPoint(aDoc, "Origin", 0., 0., 0.);
53     aFeatures.push_back(aOrigin);
54     aFeatures.push_back(createAxis(aDoc, aOrigin, 100., 0., 0.));
55     aFeatures.push_back(createAxis(aDoc, aOrigin, 0., 100., 0.));
56     aFeatures.push_back(createAxis(aDoc, aOrigin, 0., 0., 100.));
57     aFeatures.push_back(createPlane(aDoc, 1., 0., 0.));
58     aFeatures.push_back(createPlane(aDoc, 0., -1., 0.));
59     aFeatures.push_back(createPlane(aDoc, 0., 0., 1.));
60     // for PartSet it is done outside of the transaction, so explicitly flush this creation
61     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
62
63     // hides the created features, the precondition is that the feature's results have been
64     // already built, so the createPlane/Points method calls the execute function for the planes
65     std::list<FeaturePtr >::const_iterator aFIter = aFeatures.begin();
66     for (; aFIter != aFeatures.cend(); aFIter++) {
67       FeaturePtr aPlane = *aFIter;
68       const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aPlane->results();
69       std::list<ResultPtr >::const_iterator aRIter = aResults.begin();
70       for (; aRIter != aResults.cend(); aRIter++) {
71         (*aRIter)->setDisplayed(false);
72       }
73     }
74     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
75
76     // the viewer update should be unblocked in order to avoid the features blinking before they are
77     // hidden
78     aMsg = std::shared_ptr<Events_Message>(
79                   new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
80
81     Events_Loop::loop()->send(aMsg);
82
83   } else if (theMessage.get()) {
84     Events_InfoMessage("InitializationPlugin_Plugin",
85         "InitializationPlugin_Plugin::processEvent: unhandled message caught: %1")
86             .arg(theMessage->eventID().eventText()).send();
87   }
88 }
89
90 FeaturePtr InitializationPlugin_Plugin::createPlane(DocumentPtr theDoc, double theX, double theY,
91                                                     double theZ)
92 {
93   FeaturePtr aPlane = theDoc->addFeature("Plane");
94   aPlane->string("creation_method")->setValue("by_general_equation");
95 #ifdef NESTED_TOOLBOX_FIX
96   aPlane->string("by_other_plane_option")->setValue("by_distance_from_other");
97   aPlane->real("distance")->setValue(0);
98 #endif
99   aPlane->real("A")->setValue(theX);
100   aPlane->real("B")->setValue(theY);
101   aPlane->real("C")->setValue(theZ);
102   aPlane->real("D")->setValue(0.);
103
104   if (theX) {
105     aPlane->data()->setName("YOZ");
106   } else if (theY) {
107     aPlane->data()->setName("XOZ");
108   } else if (theZ) {
109     aPlane->data()->setName("XOY");
110   }
111   aPlane->setInHistory(aPlane, false);  // don't show automatically created feature in the features history
112
113   // the plane should be executed in order to build the feature result immediatelly
114   // the results are to be hidden in the plugin
115   aPlane->execute();
116   // this flag is needed here to avoid setting it inside of the next transaction
117   // (may cause crash on redo of the first transaction in OCAF)
118   aPlane->data()->execState(ModelAPI_StateDone);
119   aPlane->firstResult()->data()->execState(ModelAPI_StateDone);
120
121   return aPlane;
122 }
123
124 FeaturePtr InitializationPlugin_Plugin::createPoint(DocumentPtr theDoc, const std::string& theName,
125                                                     double theX, double theY, double theZ)
126 {
127   std::shared_ptr<ModelAPI_Feature> aPoint = theDoc->addFeature("Point");
128   aPoint->string("creation_method")->setValue("by_xyz");
129   aPoint->real("x")->setValue(theX);
130   aPoint->real("y")->setValue(theY);
131   aPoint->real("z")->setValue(theZ);
132   aPoint->data()->setName(theName);
133   aPoint->setInHistory(aPoint, false);  // don't show automatically created feature in the features history
134
135   // the point should be executed in order to build the feature result immediatelly
136   // the results are to be hidden in the plugin
137   aPoint->execute();
138   aPoint->data()->execState(ModelAPI_StateDone);
139   aPoint->firstResult()->data()->execState(ModelAPI_StateDone);
140
141   return aPoint;
142 }
143
144 FeaturePtr InitializationPlugin_Plugin::createAxis(DocumentPtr theDoc, FeaturePtr theOrigin,
145                                                    double theX, double theY, double theZ)
146 {
147   std::shared_ptr<ModelAPI_Feature> aAxis = theDoc->addFeature("Axis");
148   aAxis->string("CreationMethod")->setValue("AxisByPointAndDirection");
149
150   ResultPtr aResult = theOrigin->firstResult();
151   aAxis->selection("FirstPoint")->setValue(aResult, aResult->shape());
152
153   aAxis->real("X_Direction")->setValue(theX);
154   aAxis->real("Y_Direction")->setValue(theY);
155   aAxis->real("Z_Direction")->setValue(theZ);
156
157   if (theX != 0) {
158     aAxis->data()->setName("OX");
159   } else if (theY != 0) {
160     aAxis->data()->setName("OY");
161   } else if (theZ != 0) {
162     aAxis->data()->setName("OZ");
163   }
164   aAxis->setInHistory(aAxis, false);  // don't show automatically created feature in the features history
165   aAxis->execute();
166   aAxis->data()->execState(ModelAPI_StateDone);
167   aAxis->firstResult()->data()->execState(ModelAPI_StateDone);
168
169   return aAxis;
170 }