PeriDyno 1.2.1
Loading...
Searching...
No Matches
WtModuleFlowScene.cpp
Go to the documentation of this file.
1#include "WtModuleFlowScene.h"
2#include "WtNodeWidget.h"
4#include "AutoLayoutDAG.h"
5
6namespace dyno
7{
8 class WtStates : public Module
9 {
11 public:
13 };
14
16}
17
18Wt::WPointF SimStatePos = Wt::WPointF(0.0f, 0.0f);
19Wt::WPointF RenStatePos = Wt::WPointF(0.0f, 0.0f);
20
21WtModuleFlowScene::WtModuleFlowScene(Wt::WPainter* painter, std::shared_ptr<dyno::Node> node)
22 : _painter(painter)
23 , mNode(node)
24{
25 if(node != nullptr)
27
28 //reorderAllModules();
29}
30
34
36{
37 mEditingEnabled = true;
38
39 auto allNodes = this->allNodes();
40
41 for (auto node : allNodes)
42 {
43 auto model = dynamic_cast<WtModuleWidget*>(node->nodeDataModel());
44 if (model != nullptr)
45 {
46 model->enableEditing();
47 }
48 }
49}
50
52{
53 mEditingEnabled = false;
54
55 auto allNodes = this->allNodes();
56
57 for (auto node : allNodes)
58 {
59 auto model = dynamic_cast<WtModuleWidget*>(node->nodeDataModel());
60 if (model != nullptr)
61 {
62 model->disableEditing();
63 }
64 }
65}
66
68{
70
71 clearScene();
72
73 if (mNode != nullptr)
75
77}
78
80{
81 if (mActivePipeline == nullptr)
82 return;
83
85
86 auto constructDAG = [&](std::shared_ptr<dyno::Module> m) -> void
87 {
88 auto outId = m->objectId();
89
90 auto fieldOut = m->getOutputFields();
91
92 for (int i = 0; i < fieldOut.size(); i++)
93 {
94 auto& sinks = fieldOut[i]->getSinks();
95 for (auto sink : sinks)
96 {
97 if (sink != nullptr)
98 {
99 auto parSrc = sink->parent();
100 if (parSrc != nullptr)
101 {
102 dyno::Module* nodeSrc = dynamic_cast<dyno::Module*>(parSrc);
103
104 if (nodeSrc != nullptr)
105 {
106 auto inId = nodeSrc->objectId();
107 graph.addEdge(outId, inId);
108 }
109 }
110 }
111 }
112 }
113 };
114
115 constructDAG(mStates);
116
117 auto& mlists = mActivePipeline->activeModules();
118 for (auto it = mlists.begin(); it != mlists.end(); it++)
119 constructDAG(*it);
120
121 dyno::AutoLayoutDAG layout(&graph);
122 layout.update();
123
124 //Set up the mapping from ObjectId to WtNode
125 auto& _nodes = this->nodes();
126 std::map<dyno::ObjectId, WtNode*> wtNodeMapper;
127 std::map<dyno::ObjectId, dyno::Module*> moduleMapper;
128 for (auto const& _node : _nodes)
129 {
130 auto const& wtNode = _node.second;
131 auto model = wtNode->nodeDataModel();
132
133 auto nodeData = dynamic_cast<WtModuleWidget*>(model);
134
135 if (model != nullptr)
136 {
137 auto m = nodeData->getModule();
138 if (m != nullptr)
139 {
140 wtNodeMapper[m->objectId()] = wtNode.get();
141 moduleMapper[m->objectId()] = m.get();
142 }
143 }
144 }
145
146 float offsetX = 0.0f;
147 for (size_t l = 0; l < layout.layerNumber(); l++)
148 {
149 auto& xc = layout.layer(l);
150
151 float offsetY = 0.0f;
152 float xMax = 0.0f;
153 for (size_t index = 0; index < xc.size(); index++)
154 {
155 dyno::ObjectId id = xc[index];
156 if (wtNodeMapper.find(id) != wtNodeMapper.end())
157 {
158 WtNode* wtNode = wtNodeMapper[id];
159 WtNodeGeometry& geo = wtNode->nodeGeometry();
160
161 float w = geo.width();
162 float h = geo.height();
163
164 xMax = std::max(xMax, w);
165
166 Module* node = moduleMapper[id];
167
168 node->setBlockCoord(offsetX, offsetY);
169
170 offsetY += (h + mDy);
171 }
172 }
173
174 offsetX += (xMax + mDx);
175 }
176
177 if (mActivePipeline == mNode->animationPipeline()) {
178 SimStatePos = Wt::WPointF(mStates->bx(), mStates->by());
179 }
180 else {
181 RenStatePos = Wt::WPointF(mStates->bx(), mStates->by());
182 }
183
184
185 wtNodeMapper.clear();
186 moduleMapper.clear();
187
189}
190
191void WtModuleFlowScene::showModuleFlow(std::shared_ptr<dyno::Node> node)
192{
193 //clearScene();
194
195 if (node == nullptr)
196 return;
197
198 auto& mlist = node->getModuleList();
199
200 std::map<dyno::ObjectId, WtNode*> moduleMap;
201
202 // To show the animation pipeline
203 if (mActivePipeline == nullptr)
204 mActivePipeline = node->graphicsPipeline();
205
206 auto& modules = mActivePipeline->allModules();
207
208 auto addModuleWidget = [&](std::shared_ptr<dyno::Module> m) -> void
209 {
210 auto mId = m->objectId();
211
212 auto type = std::make_unique<WtModuleWidget>(m);
213
214 auto& node = this->createNode(std::move(type), _painter, -1);
215
216 node.setModule(m);
217
218 moduleMap[mId] = &node;
219
220 OutNodeMap[mId] = &node;
221
222 Wt::WPointF posView(m->bx(), m->by());
223
224 node.nodeGraphicsObject().setPos(posView);
225 //this->nodePlaced(node);
226 };
227
228 //Create a dummy module to store all state variables
229 mStates = std::make_shared<dyno::WtStates>();
230
231 auto& fields = node->getAllFields();
232 for (auto field : fields)
233 {
234 if (field->getFieldType() == dyno::FieldTypeEnum::State
235 || field->getFieldType() == dyno::FieldTypeEnum::In)
236 {
237 mStates->addOutputField(field);
238 }
239 }
240
241 Wt::WPointF pos = mActivePipeline == node->animationPipeline() ? SimStatePos : RenStatePos;
242 mStates->setBlockCoord(pos.x(), pos.y());
243
244 addModuleWidget(mStates);
245
246 for (auto m : modules)
247 {
248 addModuleWidget(m.second);
249 }
250
251 auto createModuleConnections = [&](std::shared_ptr<dyno::Module> m)->void
252 {
253 auto inId = m->objectId();
254
255 if (moduleMap.find(inId) != moduleMap.end())
256 {
257 auto inBlock = moduleMap[m->objectId()];
258
259 auto fieldIn = m->getInputFields();
260
261 for (int i = 0; i < fieldIn.size(); i++)
262 {
263 auto fieldSrc = fieldIn[i]->getSource();
264 if (fieldSrc != nullptr)
265 {
266 auto parSrc = fieldSrc->parent();
267 if (parSrc != nullptr)
268 {
269 dyno::Module* nodeSrc = dynamic_cast<dyno::Module*>(parSrc);
270 if (nodeSrc == nullptr)
271 nodeSrc = mStates.get();
272
273 auto outId = nodeSrc->objectId();
274 auto fieldsOut = nodeSrc->getOutputFields();
275
276 unsigned int outFieldIndex = 0;
277 bool fieldFound = false;
278 for (auto f : fieldsOut)
279 {
280 if (f == fieldSrc)
281 {
282 fieldFound = true;
283 break;
284 }
285 outFieldIndex++;
286 }
287
288 if (fieldFound && moduleMap.find(outId) != moduleMap.end())
289 {
290 auto outBlock = moduleMap[outId];
291 createConnection(*inBlock, i, *outBlock, outFieldIndex, _painter);
292 }
293 }
294 }
295 }
296 }
297 };
298
299 for (auto m : modules)
300 {
301 createModuleConnections(m.second);
302 }
303}
304
306{
307 auto pipeline = mNode->resetPipeline();
308
309 if (mNode == nullptr || mActivePipeline == pipeline)
310 return;
311
312 mActivePipeline = pipeline;
313
315}
316
318{
319 auto pipeline = mNode->animationPipeline();
320
321 if (mNode == nullptr || mActivePipeline == pipeline)
322 return;
323
324 mActivePipeline = pipeline;
325
327}
328
330{
331 auto pipeline = mNode->graphicsPipeline();
332
333 if (mNode == nullptr || mActivePipeline == pipeline)
334 return;
335
336 mActivePipeline = pipeline;
337
339}
#define IMPLEMENT_CLASS(name)
Definition Object.h:79
Wt::WPointF RenStatePos
Wt::WPointF SimStatePos
std::vector< WtNode * > allNodes() const
WtNode & createNode(std::unique_ptr< WtNodeDataModel > &&dataModel, Wt::WPainter *painter, int selectType)
std::map< dyno::ObjectId, WtNode * > OutNodeMap
std::shared_ptr< WtConnection > createConnection(PortType connectedPort, WtNode &node, PortIndex portIndex, Wt::WPainter *painter)
std::unordered_map< Wt::Guid, std::unique_ptr< WtNode > > const & nodes() const
void clearScene()
std::unordered_map< Wt::Guid, UniqueNode > _nodes
std::shared_ptr< dyno::Pipeline > mActivePipeline
std::shared_ptr< dyno::Module > mStates
void showModuleFlow(std::shared_ptr< dyno::Node > node)
WtModuleFlowScene(Wt::WPainter *painter, std::shared_ptr< dyno::Node > node)
std::shared_ptr< dyno::Node > mNode
Wt::WPainter * _painter
unsigned int width() const
Definition WtNode.h:35
unsigned int height() const
Definition WtNode.h:31
WtNodeGeometry & nodeGeometry()
Definition WtNode.cpp:707
Automatic layout for directed acyclic graph Refer to "Sugiyama Algorithm" by Nikola S....
std::vector< ObjectId > & layer(size_t l)
Graph class represents a directed graph.
void addEdge(ObjectId v, ObjectId w)
Module(std::string name="default")
Definition Module.cpp:9
std::vector< FBase * > & getOutputFields()
Definition OBase.h:179
void setBlockCoord(float x, float y)
Definition OBase.h:161
ObjectId objectId()
Definition Object.h:129
DECLARE_CLASS(WtStates)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
uint32_t ObjectId
Definition Object.h:110
@ In
Definition FBase.h:31
@ State
Definition FBase.h:35