1 
2 
3 #include "toonz/tstageobjecttree.h"
4 #include "toonz/tstageobjectspline.h"
5 #include "toonz/tstageobject.h"
6 #include "tgrammar.h"
7 #include "ttokenizer.h"
8 #include "tconvert.h"
9 #include "tunit.h"
10 #include "tstream.h"
11 
12 #include "toonz/txsheet.h"
13 #include "toonz/txshcell.h"
14 
15 #include "toonz/txsheetexpr.h"
16 #include "toonz/columnfan.h"
17 #include "../include/orientation.h"
18 
19 using namespace TSyntax;
20 
21 //=============================================================================
22 //! The struct TStageObjectTree::TStageObjectTreeImp contains all element
23 //! necessary to define a pegbar tree.
24 
25 struct TStageObjectTree::TStageObjectTreeImp {
26   enum DagGridDimension { eLarge = 0, eSmall = 1 };
27 
28   //! The map contains generic pegbar of pegbar tree.
29   std::map<TStageObjectId, TStageObject *> m_pegbarTable;
30 
31   //! Define pegbar tree current camera .
32   TStageObjectId m_currentCameraId;
33   TStageObjectId m_currentPreviewCameraId;
34 
35   //! Allows to manager pegbar handle.
36   HandleManager *m_handleManager;
37 
38   //! The vector contains all spline \b TStageObjectSpline of pegbar tree.
39   std::map<int, TStageObjectSpline *> m_splines;
40 
41   int m_cameraCount;
42   int m_groupIdCount;
43   int m_splineCount;
44   int m_dagGridDimension;
45 
46   Grammar *m_grammar;
47 
48   /*!
49 Constructs a TStageObjectTreeImp with default value.
50 */
51   TStageObjectTreeImp();
52   /*!
53 Destroys the TStageObjectTreeImp object.
54 */
55   ~TStageObjectTreeImp();
56 
57   // not implemented
58   TStageObjectTreeImp(const TStageObjectTreeImp &);
59   TStageObjectTreeImp &operator=(const TStageObjectTreeImp &);
60 };
61 
62 //-----------------------------------------------------------------------------
63 
TStageObjectTreeImp()64 TStageObjectTree::TStageObjectTreeImp::TStageObjectTreeImp()
65     : m_currentCameraId(TStageObjectId::CameraId(0))
66     , m_currentPreviewCameraId(TStageObjectId::CameraId(0))
67     , m_handleManager(0)
68     , m_cameraCount(0)
69     , m_groupIdCount(0)
70     , m_splineCount(0)
71     , m_grammar(0)
72     , m_dagGridDimension(eSmall) {}
73 
74 //-----------------------------------------------------------------------------
75 
~TStageObjectTreeImp()76 TStageObjectTree::TStageObjectTreeImp::~TStageObjectTreeImp() {
77   std::map<TStageObjectId, TStageObject *>::iterator i;
78   for (i = m_pegbarTable.begin(); i != m_pegbarTable.end(); ++i)
79     i->second->release();
80   std::map<int, TStageObjectSpline *>::iterator it;
81   for (it = m_splines.begin(); it != m_splines.end(); it++)
82     it->second->release();
83   delete m_grammar;
84 }
85 
86 //=============================================================================
87 // TStageObjectTree
88 
TStageObjectTree()89 TStageObjectTree::TStageObjectTree() : m_imp(new TStageObjectTreeImp) {
90   getStageObject(TStageObjectId::CameraId(0), true);
91   getStageObject(TStageObjectId::TableId, true);
92 
93 /*
94   static bool firstTime = true;
95   if(firstTime)
96   {
97     firstTime = false;
98     Grammar*grammar = ExprGrammar::instance();
99     grammar->addPattern("leaf", new ParamReferencePattern());
100   }
101 */
102 #ifndef NDEBUG
103   checkIntegrity();
104 #endif
105 }
106 
107 //-----------------------------------------------------------------------------
108 
~TStageObjectTree()109 TStageObjectTree::~TStageObjectTree() {}
110 
111 //-----------------------------------------------------------------------------
112 
checkIntegrity()113 void TStageObjectTree::checkIntegrity() {
114   std::map<TStageObjectId, TStageObject *> &pegbars     = m_imp->m_pegbarTable;
115   std::map<TStageObjectId, TStageObject *>::iterator it = pegbars.begin();
116   int minColumnIndex = 0;
117   int maxColumnIndex = -1;
118   std::set<int> columnIndexTable;
119 
120   int cameraCount = 0;
121   for (; it != pegbars.end(); ++it) {
122     TStageObjectId id = it->first;
123     TStageObject *imp = it->second;
124     assert(imp->getId() == id);
125     if (id.isColumn()) {
126       int index = id.getIndex();
127       if (minColumnIndex > maxColumnIndex)
128         minColumnIndex = maxColumnIndex = index;
129       else {
130         if (index < minColumnIndex) minColumnIndex = index;
131         if (index > maxColumnIndex) maxColumnIndex = index;
132       }
133       assert(columnIndexTable.find(index) == columnIndexTable.end());
134       columnIndexTable.insert(index);
135     } else if (id.isPegbar()) {
136       assert(imp->getParent() != TStageObjectId());
137       assert(imp->getParent().isPegbar() || imp->getParent().isTable());
138     } else if (id.isTable())
139       assert(imp->getParent() == TStageObjectId());
140     else if (id.isCamera())  // la camera puo' essere attaccata dovunque
141       cameraCount++;
142     else
143       assert(0);
144   }
145   if (minColumnIndex > maxColumnIndex) {
146     assert(columnIndexTable.size() == 0);
147   } else {
148     assert(minColumnIndex == 0);
149     int count = maxColumnIndex - minColumnIndex + 1;
150     int m     = columnIndexTable.size();
151     assert(m == count);
152     int k = minColumnIndex;
153     for (std::set<int>::iterator it = columnIndexTable.begin();
154          it != columnIndexTable.end(); ++it) {
155       assert(*it == k);
156       k++;
157     }
158   }
159   assert(m_imp->m_cameraCount == cameraCount);
160 }
161 
162 //-----------------------------------------------------------------------------
163 
getStageObject(const TStageObjectId & id,bool create)164 TStageObject *TStageObjectTree::getStageObject(const TStageObjectId &id,
165                                                bool create) {
166   std::map<TStageObjectId, TStageObject *> &pegbars     = m_imp->m_pegbarTable;
167   std::map<TStageObjectId, TStageObject *>::iterator it = pegbars.find(id);
168   if (it != pegbars.end()) {
169     TStageObject *pegbar = it->second;
170     return pegbar;
171   } else if (create) {
172     TStageObject *pegbar = new TStageObject(this, id);
173     if (id.isColumn()) {
174       int index = id.getIndex();
175       // mi assicuro che esistano tutte le colonne con indici inferiori
176       if (index > 0) getStageObject(TStageObjectId::ColumnId(index - 1));
177       // assegno il parent (per una colonna dev'essere la table)
178       TStageObjectId parentId = TStageObjectId::TableId;
179       pegbar->setParent(parentId);
180       // mi assicuro che il padre esista
181       getStageObject(parentId);
182     } else if (id.isPegbar()) {
183       pegbar->setParent(TStageObjectId::TableId);
184     } else if (id.isCamera())
185       m_imp->m_cameraCount++;
186     pegbars[id] = pegbar;
187     pegbar->addRef();
188 
189 #ifndef NDEBUG
190     checkIntegrity();
191 #endif
192 
193     return pegbar;
194   } else
195     return 0L;
196 }
197 
198 //-----------------------------------------------------------------------------
199 
insertColumn(int index)200 void TStageObjectTree::insertColumn(int index) {
201   assert(0 <= index);
202 #ifndef NDEBUG
203   checkIntegrity();
204 #endif
205 
206   TStageObjectId id       = TStageObjectId::ColumnId(index);
207   TStageObject *pegbar    = new TStageObject(this, id);
208   TStageObjectId parentId = TStageObjectId::TableId;
209   pegbar->setParent(parentId);
210   // mi assicuro che il padre esista
211   getStageObject(parentId);
212 
213   // mi assicuro che esistano tutte le colonne di indice inferiore
214   for (int k = 0; k < index; k++) getStageObject(TStageObjectId::ColumnId(k));
215 
216   std::map<TStageObjectId, TStageObject *> &pegbars = m_imp->m_pegbarTable;
217 
218   std::vector<std::pair<TStageObjectId, TStageObject *>> tmp(pegbars.begin(),
219                                                              pegbars.end());
220   std::vector<std::pair<TStageObjectId, TStageObject *>>::iterator it;
221 
222   for (it = tmp.begin(); it != tmp.end(); ++it) {
223     TStageObjectId j = it->first;
224     if (j.isColumn() && j.getIndex() >= index) {
225       it->first = TStageObjectId::ColumnId(j.getIndex() + 1);
226       it->second->setId(it->first);
227     }
228   }
229 
230   pegbars.clear();
231   pegbars.insert(tmp.begin(), tmp.end());
232 
233   pegbars[id] = pegbar;
234   pegbar->addRef();
235 
236 #ifndef NDEBUG
237   checkIntegrity();
238 #endif
239 }
240 
241 //-----------------------------------------------------------------------------
242 
removeColumn(int index)243 void TStageObjectTree::removeColumn(int index) {
244   assert(0 <= index);
245 
246   TStageObjectId id = TStageObjectId::ColumnId(index);
247   std::map<TStageObjectId, TStageObject *> &pegbars = m_imp->m_pegbarTable;
248   std::map<TStageObjectId, TStageObject *>::iterator pit;
249   pit                           = pegbars.find(id);
250   TStageObject *imp             = 0;
251   if (pit != pegbars.end()) imp = pit->second;
252 
253   if (imp) {
254     // i figli della colonna rimossa si attaccano al "nonno"
255     TStageObjectId parentId = imp->getParent();
256     imp->detachFromParent();
257     /* while(! m_children.empty())
258 {
259 TStageObject*son = *imp->m_children.begin();
260 son->setParent(parentId);
261 }*/
262     imp->attachChildrenToParent(parentId);
263     imp->release();
264   }
265   imp = 0;
266 
267   pegbars.erase(id);
268   std::vector<std::pair<TStageObjectId, TStageObject *>> tmp(pegbars.begin(),
269                                                              pegbars.end());
270   std::vector<std::pair<TStageObjectId, TStageObject *>>::iterator it;
271   for (it = tmp.begin(); it != tmp.end(); ++it) {
272     TStageObjectId j = it->first;
273     if (j.isColumn() && j.getIndex() > index) {
274       it->first = TStageObjectId::ColumnId(j.getIndex() - 1);
275       it->second->setId(it->first);
276     }
277   }
278 
279   pegbars.clear();
280   pegbars.insert(tmp.begin(), tmp.end());
281 
282 #ifndef NDEBUG
283   checkIntegrity();
284 #endif
285 }
286 
287 //-----------------------------------------------------------------------------
288 
removeStageObject(const TStageObjectId & id)289 void TStageObjectTree::removeStageObject(const TStageObjectId &id) {
290   std::map<TStageObjectId, TStageObject *> &pegbars = m_imp->m_pegbarTable;
291   assert(pegbars.count(id) > 0);
292   TStageObject *obj = pegbars[id];
293   obj->attachChildrenToParent(obj->getParent());
294   obj->detachFromParent();
295   obj->release();
296   pegbars.erase(id);
297   if (id.isCamera()) m_imp->m_cameraCount--;
298 #ifndef NDEBUG
299   checkIntegrity();
300 #endif
301 }
302 
303 //-----------------------------------------------------------------------------
304 
insertStageObject(TStageObject * pegbar)305 void TStageObjectTree::insertStageObject(TStageObject *pegbar) {
306   TStageObject *imp = dynamic_cast<TStageObject *>(pegbar);
307   assert(imp);
308   TStageObjectId id = imp->getId();
309   std::map<TStageObjectId, TStageObject *> &pegbars = m_imp->m_pegbarTable;
310   assert(pegbars.count(id) == 0);
311   pegbars[id] = imp;
312   imp->addRef();
313   imp->setParent(imp->getParent());
314   if (id.isCamera()) m_imp->m_cameraCount++;
315 #ifndef NDEBUG
316   checkIntegrity();
317 #endif
318 }
319 
320 //-----------------------------------------------------------------------------
321 namespace {  // Utility Function
322 //-----------------------------------------------------------------------------
checkId(TStageObjectTree * tree,const TStageObjectId & id)323 bool checkId(TStageObjectTree *tree, const TStageObjectId &id) {
324   TStageObject *pegbar = tree->getStageObject(id, false);
325   return !pegbar || pegbar->getId() == id;
326 }
327 //-----------------------------------------------------------------------------
328 }  // namespace
329 //-----------------------------------------------------------------------------
330 
swapColumns(int i,int j)331 void TStageObjectTree::swapColumns(int i, int j) {
332   if (i == j) return;
333   if (i > j) std::swap(i, j);
334   std::map<TStageObjectId, TStageObject *> &pegbars = m_imp->m_pegbarTable;
335   std::map<TStageObjectId, TStageObject *>::iterator iti, itj;
336   std::map<TStageObjectId, TStageObject *>::const_iterator end = pegbars.end();
337   TStageObjectId idi = TStageObjectId::ColumnId(i);
338   TStageObjectId idj = TStageObjectId::ColumnId(j);
339   assert(checkId(this, idi));
340   assert(checkId(this, idj));
341 
342   iti = pegbars.find(idi);
343   itj = pegbars.find(idj);
344 
345   if (iti == end && itj == end) {
346   } else if (iti != end && itj != end) {
347     assert(iti->second);
348     assert(itj->second);
349     std::swap(iti->second, itj->second);
350     iti->second->setId(iti->first);
351     itj->second->setId(itj->first);
352   } else if (iti == end) {
353     // iti e' il minore. Se manca iti deve mancare anche itj
354     assert(0);
355   } else {
356     // manca itj, ma iti c'e'. Devo crearne uno per evitare i buchi
357     assert(iti != end);
358     assert(iti->second);
359     assert(itj == end);
360     pegbars[idj] = iti->second;
361     iti->second->setId(idj);
362     pegbars.erase(iti);
363 
364     // creo
365     getStageObject(idi, true);
366   }
367   assert(checkId(this, idi));
368   assert(checkId(this, idj));
369 
370 #ifndef NDEBUG
371   checkIntegrity();
372 #endif
373 }
374 
375 //-----------------------------------------------------------------------------
376 
loadData(TIStream & is,TXsheet * xsh)377 void TStageObjectTree::loadData(TIStream &is, TXsheet *xsh) {
378   std::string tagName;
379   while (is.matchTag(tagName)) {
380     if (tagName == "splines") {
381       while (!is.eos()) {
382         TPersist *p = 0;
383         is >> p;
384         TStageObjectSpline *spline = dynamic_cast<TStageObjectSpline *>(p);
385         insertSpline(spline);
386       }
387       is.matchEndTag();
388     } else if (tagName == "pegbar") {
389       std::string idStr = is.getTagAttribute("id");
390       if (idStr == "")  // vecchio formato
391       {
392         is >> idStr;
393       }
394       TStageObjectId id = toStageObjectId(idStr);
395       if (id.isCamera() && is.getTagAttribute("active") == "yes")
396         m_imp->m_currentCameraId = id;
397       else if (id.isCamera() && is.getTagAttribute("activepreview") == "yes")
398         m_imp->m_currentPreviewCameraId = id;
399       else if (id.isCamera() && is.getTagAttribute("activeboth") == "yes")
400         m_imp->m_currentPreviewCameraId = m_imp->m_currentCameraId = id;
401 
402       if (id.isCamera()) {
403         if (is.getTagAttribute("columnLocked") == "yes")
404           xsh->setCameraColumnLocked(true);
405         if (is.getTagAttribute("columnFolded") == "yes")
406           xsh->getColumnFan(Orientations::topToBottom())->deactivate(-1);
407       }
408 
409       TStageObject *pegbar =
410           dynamic_cast<TStageObject *>(getStageObject(id, true));
411       if (!pegbar)
412         throw TException("TStageObjectTree::loadData. can't create the pegbar");
413       pegbar->loadData(is);
414       if (pegbar->isGrouped() && m_imp->m_groupIdCount < pegbar->getGroupId())
415         m_imp->m_groupIdCount = pegbar->getGroupId();
416       is.matchEndTag();
417 
418       std::string name = pegbar->getName();
419     } else if (tagName == "grid_dimension") {
420       is >> m_imp->m_dagGridDimension;
421       is.matchEndTag();
422     } else
423       throw TException("pegbartree: unexpected tag : " + tagName);
424   }
425 
426 #ifndef NDEBUG
427   checkIntegrity();
428 #endif
429 }
430 
431 //-----------------------------------------------------------------------------
432 
saveData(TOStream & os,int occupiedColumnCount,TXsheet * xsh)433 void TStageObjectTree::saveData(TOStream &os, int occupiedColumnCount,
434                                 TXsheet *xsh) {
435   std::map<TStageObjectId, TStageObject *>::iterator it;
436   std::map<TStageObjectId, TStageObject *> &pegbars = m_imp->m_pegbarTable;
437   if (!m_imp->m_splines.empty()) {
438     os.openChild("splines");
439     std::map<int, TStageObjectSpline *>::iterator it;
440     for (it = m_imp->m_splines.begin(); it != m_imp->m_splines.end(); it++) {
441       os << it->second;
442     }
443     os.closeChild();
444   }
445   for (it = pegbars.begin(); it != pegbars.end(); ++it) {
446     TStageObjectId objectId = it->first;
447     TStageObject *pegbar    = it->second;
448 
449     if (objectId.isColumn() && objectId.getIndex() >= occupiedColumnCount)
450       continue;
451 
452     std::map<std::string, std::string> attr;
453     attr["id"] = objectId.toString();
454     if (objectId == m_imp->m_currentCameraId &&
455         objectId == m_imp->m_currentPreviewCameraId)
456       attr["activeboth"] = "yes";
457     else if (objectId == m_imp->m_currentCameraId)
458       attr["active"] = "yes";
459     else if (objectId == m_imp->m_currentPreviewCameraId)
460       attr["activepreview"] = "yes";
461 
462     // Since we don't have a real column and we want the files to open in
463     // older versions, we'll store column settings on the camera pegbar
464     if ((objectId == m_imp->m_currentCameraId ||
465          objectId == m_imp->m_currentPreviewCameraId)) {
466       if (xsh->isCameraColumnLocked()) attr["columnLocked"] = "yes";
467       if (!xsh->getColumnFan(Orientations::topToBottom())->isActive(-1))
468         attr["columnFolded"] = "yes";
469     }
470 
471     os.openChild("pegbar", attr);
472 
473     pegbar->saveData(os);
474     os.closeChild();
475   }
476   os.child("grid_dimension") << (int)m_imp->m_dagGridDimension;
477 }
478 
479 //-----------------------------------------------------------------------------
480 
getStageObjectCount() const481 int TStageObjectTree::getStageObjectCount() const {
482   return m_imp->m_pegbarTable.size();
483 }
484 
485 //-----------------------------------------------------------------------------
486 
getCameraCount() const487 int TStageObjectTree::getCameraCount() const { return m_imp->m_cameraCount; }
488 
489 //-----------------------------------------------------------------------------
490 
getNewGroupId()491 int TStageObjectTree::getNewGroupId() { return ++m_imp->m_groupIdCount; }
492 
493 //-----------------------------------------------------------------------------
494 
getStageObject(int index) const495 TStageObject *TStageObjectTree::getStageObject(int index) const {
496   assert(0 <= index && index < getStageObjectCount());
497   std::map<TStageObjectId, TStageObject *>::const_iterator it;
498   int i = 0;
499   for (it = m_imp->m_pegbarTable.begin();
500        it != m_imp->m_pegbarTable.end() && i < index; ++it, ++i) {
501   }
502   assert(it != m_imp->m_pegbarTable.end());
503   return it->second;
504 }
505 
506 //-----------------------------------------------------------------------------
507 
getCurrentCameraId() const508 TStageObjectId TStageObjectTree::getCurrentCameraId() const {
509   return m_imp->m_currentCameraId;
510 }
511 
512 //-----------------------------------------------------------------------------
513 
getCurrentPreviewCameraId() const514 TStageObjectId TStageObjectTree::getCurrentPreviewCameraId() const {
515   return m_imp->m_currentPreviewCameraId;
516 }
517 
518 //-----------------------------------------------------------------------------
519 
setCurrentCameraId(const TStageObjectId & id)520 void TStageObjectTree::setCurrentCameraId(const TStageObjectId &id) {
521   assert(id.isCamera());
522   m_imp->m_currentCameraId = id;
523 }
524 
525 //-----------------------------------------------------------------------------
526 
setCurrentPreviewCameraId(const TStageObjectId & id)527 void TStageObjectTree::setCurrentPreviewCameraId(const TStageObjectId &id) {
528   assert(id.isCamera());
529   m_imp->m_currentPreviewCameraId = id;
530 }
531 
532 //-----------------------------------------------------------------------------
533 
invalidateAll()534 void TStageObjectTree::invalidateAll() {
535   std::map<TStageObjectId, TStageObject *>::iterator it;
536   for (it = m_imp->m_pegbarTable.begin(); it != m_imp->m_pegbarTable.end();
537        ++it) {
538     it->second->invalidate();
539   }
540 }
541 
542 //-----------------------------------------------------------------------------
543 
setHandleManager(HandleManager * hm)544 void TStageObjectTree::setHandleManager(HandleManager *hm) {
545   m_imp->m_handleManager = hm;
546 }
547 
548 //-----------------------------------------------------------------------------
549 
getHandlePos(const TStageObjectId & id,std::string handle,int row) const550 TPointD TStageObjectTree::getHandlePos(const TStageObjectId &id,
551                                        std::string handle, int row) const {
552   if (m_imp->m_handleManager)
553     return m_imp->m_handleManager->getHandlePos(id, handle, row);
554   else
555     return TPointD();
556 }
557 
558 //-----------------------------------------------------------------------------
559 
getSplineCount() const560 int TStageObjectTree::getSplineCount() const { return m_imp->m_splines.size(); }
561 
562 //-----------------------------------------------------------------------------
563 
getSpline(int index) const564 TStageObjectSpline *TStageObjectTree::getSpline(int index) const {
565   assert(0 <= index && index < getSplineCount());
566   std::map<int, TStageObjectSpline *>::iterator it = m_imp->m_splines.begin();
567   for (int i = 0; i < index; i++) it++;
568   return it->second;
569 }
570 
571 //-----------------------------------------------------------------------------
572 
getSplineById(int splineId) const573 TStageObjectSpline *TStageObjectTree::getSplineById(int splineId) const {
574   std::map<int, TStageObjectSpline *>::iterator it =
575       m_imp->m_splines.find(splineId);
576   if (it != m_imp->m_splines.end()) return it->second;
577   return 0;
578 }
579 
580 //-----------------------------------------------------------------------------
581 
createSpline()582 TStageObjectSpline *TStageObjectTree::createSpline() {
583   TStageObjectSpline *spline = new TStageObjectSpline();
584   spline->setId(m_imp->m_splineCount++);
585   m_imp->m_splines[spline->getId()] = spline;
586   spline->addRef();
587   return spline;
588 }
589 
590 //-----------------------------------------------------------------------------
591 
assignUniqueSplineId(TStageObjectSpline * spline)592 void TStageObjectTree::assignUniqueSplineId(TStageObjectSpline *spline) {
593   if (!spline) return;
594   spline->setId(m_imp->m_splineCount++);
595 }
596 
597 //-----------------------------------------------------------------------------
598 
removeSpline(TStageObjectSpline * spline)599 void TStageObjectTree::removeSpline(TStageObjectSpline *spline) {
600   assert(spline->getId() >= 0);
601   std::map<int, TStageObjectSpline *> &splines = m_imp->m_splines;
602   std::map<int, TStageObjectSpline *>::iterator it;
603   it = splines.find(spline->getId());
604   if (it == splines.end()) return;
605   splines.erase(it);
606   assert(!containsSpline(spline));
607   spline->release();
608 }
609 
610 //-----------------------------------------------------------------------------
611 
containsSpline(TStageObjectSpline * s) const612 bool TStageObjectTree::containsSpline(TStageObjectSpline *s) const {
613   assert(s->getId() >= 0);
614   std::map<int, TStageObjectSpline *> &splines     = m_imp->m_splines;
615   std::map<int, TStageObjectSpline *>::iterator it = splines.find(s->getId());
616   return it != splines.end() && s == it->second;
617 }
618 
619 //-----------------------------------------------------------------------------
620 
insertSpline(TStageObjectSpline * s)621 void TStageObjectTree::insertSpline(TStageObjectSpline *s) {
622   assert(s->getId() >= 0);
623   std::map<int, TStageObjectSpline *> &splines = m_imp->m_splines;
624   if (containsSpline(s)) return;
625   splines[s->getId()]  = s;
626   m_imp->m_splineCount = std::max(m_imp->m_splineCount, s->getId() + 1);
627   s->addRef();
628 }
629 
630 //-----------------------------------------------------------------------------
631 
createGrammar(TXsheet * xsh)632 void TStageObjectTree::createGrammar(TXsheet *xsh) {
633   assert(!m_imp->m_grammar);
634   m_imp->m_grammar = createXsheetGrammar(xsh);
635 
636   std::map<TStageObjectId, TStageObject *>::iterator it;
637   for (it = m_imp->m_pegbarTable.begin(); it != m_imp->m_pegbarTable.end();
638        ++it) {
639     TStageObject *obj = it->second;
640 
641     int c, cCount = TStageObject::T_ChannelCount;
642     for (c = 0; c != cCount; ++c)
643       obj->getParam((TStageObject::Channel)c)->setGrammar(m_imp->m_grammar);
644 
645     if (const PlasticSkeletonDeformationP &sd =
646             obj->getPlasticSkeletonDeformation())
647       sd->setGrammar(m_imp->m_grammar);
648   }
649 }
650 
651 //-----------------------------------------------------------------------------
652 
setGrammar(const TDoubleParamP & param)653 void TStageObjectTree::setGrammar(const TDoubleParamP &param) {
654   if (m_imp->m_grammar) param->setGrammar(m_imp->m_grammar);
655 }
656 
657 //-----------------------------------------------------------------------------
658 
getGrammar() const659 TSyntax::Grammar *TStageObjectTree::getGrammar() const {
660   return m_imp->m_grammar;
661 }
662 
663 //-----------------------------------------------------------------------------
664 /*
665 void TStageObjectTree::setToonzBuilder(const TDoubleParamP &param)
666 {
667 //  param->setBuilder(new ToonzCalcNodeBuilder(this));
668 }
669 */
670 
671 //-----------------------------------------------------------------------------
672 
getCamera(const TStageObjectId & cameraId)673 TCamera *TStageObjectTree::getCamera(const TStageObjectId &cameraId) {
674   assert(cameraId.isCamera());
675   TStageObject *cameraPegbar = getStageObject(cameraId);
676   assert(cameraPegbar);
677   return cameraPegbar->getCamera();
678 }
679 
680 //-----------------------------------------------------------------------------
681 
setDagGridDimension(int dim)682 void TStageObjectTree::setDagGridDimension(int dim) {
683   m_imp->m_dagGridDimension = dim;
684 }
685 
686 //-----------------------------------------------------------------------------
687 
getDagGridDimension() const688 int TStageObjectTree::getDagGridDimension() const {
689   return m_imp->m_dagGridDimension;
690 }
691 
692 //-----------------------------------------------------------------------------
693 
694 PERSIST_IDENTIFIER(TStageObjectTree, "PegbarTree");
695