Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tdoubleparam.h"
Toshihiro Shimizu 890ddd
#include "tparamcontainer.h"
Toshihiro Shimizu 890ddd
#include "tparamset.h"
Toshihiro Shimizu 890ddd
#include "texpression.h"
Toshihiro Shimizu 890ddd
#include "tparser.h"
Toshihiro Shimizu 890ddd
#include "tfx.h"
shun-iwasawa 4a3868
#include "tzeraryfx.h"
shun-iwasawa 4a3868
#include "tcolumnset.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tw/stringtable.h"
Toshihiro Shimizu 890ddd
#include "tunit.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectid.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
shun-iwasawa 4a3868
#include "toonz/tstageobjecttree.h"
shun-iwasawa 4a3868
#include "toonz/tcolumnfxset.h"
shun-iwasawa 4a3868
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Boost includes
Toshihiro Shimizu 890ddd
#include "boost/noncopyable.hpp"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qstring></qstring>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/txsheetexpr.h"
Toshihiro Shimizu 890ddd
Campbell Barton 40cabe
#include <memory></memory>
Campbell Barton 40cabe
Toshihiro Shimizu 890ddd
using namespace TSyntax;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace  stuff
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ParamDependencyFinder final : public TSyntax::CalculatorNodeVisitor {
Shinya Kitaoka 120a6e
  TDoubleParam *m_possiblyDependentParam;
Shinya Kitaoka 120a6e
  bool m_found;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ParamDependencyFinder(TDoubleParam *possiblyDependentParam)
Shinya Kitaoka 120a6e
      : m_possiblyDependentParam(possiblyDependentParam), m_found(false) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void check(TDoubleParam *param) {
Shinya Kitaoka 120a6e
    if (param == m_possiblyDependentParam) m_found = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool found() const { return m_found; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
shun-iwasawa 4a3868
/*
shun-iwasawa 4a3868
class ColumnReferenceFinder final : public TSyntax::CalculatorNodeVisitor {
shun-iwasawa 4a3868
  QSet<int> m_indices;</int>
shun-iwasawa 4a3868
shun-iwasawa 4a3868
public:
shun-iwasawa 4a3868
  ColumnReferenceFinder() {}
shun-iwasawa 4a3868
shun-iwasawa 4a3868
  void registerColumnIndex(int columnIndex) { m_indices.insert(columnIndex); }
shun-iwasawa 4a3868
shun-iwasawa 4a3868
  QSet<int> indices() const { return m_indices; }</int>
shun-iwasawa 4a3868
};
shun-iwasawa 4a3868
*/
shun-iwasawa 4a3868
//===================================================================
shun-iwasawa 4a3868
shun-iwasawa 4a3868
class ParamReferenceFinder final : public TSyntax::CalculatorNodeVisitor {
shun-iwasawa 4a3868
  QSet<tdoubleparam *=""> m_refParams;</tdoubleparam>
shun-iwasawa 4a3868
  QSet<int> m_columnIndices;</int>
shun-iwasawa 4a3868
shun-iwasawa 4a3868
public:
shun-iwasawa 4a3868
  ParamReferenceFinder() {}
shun-iwasawa 4a3868
shun-iwasawa 4a3868
  void registerRefParam(TDoubleParam *param) { m_refParams.insert(param); }
shun-iwasawa 4a3868
  void registerColumnIndex(int columnIndex) {
shun-iwasawa 4a3868
    m_columnIndices.insert(columnIndex);
shun-iwasawa 4a3868
  }
shun-iwasawa 4a3868
shun-iwasawa 4a3868
  QSet<int> columnIndices() const { return m_columnIndices; }</int>
shun-iwasawa 4a3868
  QSet<tdoubleparam *=""> refParams() const { return m_refParams; }</tdoubleparam>
shun-iwasawa 4a3868
};
shun-iwasawa 4a3868
shun-iwasawa 4a3868
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Calculator Nodes
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 4a3868
class ParamCalculatorNode : public CalculatorNode,
shun-iwasawa 4a3868
                            public TParamObserver,
shun-iwasawa 4a3868
                            public boost::noncopyable {
Shinya Kitaoka 2a7129
  std::unique_ptr<calculatornode> m_frame;</calculatornode>
Toshihiro Shimizu 890ddd
shun-iwasawa 4a3868
protected:
shun-iwasawa 4a3868
  TDoubleParamP m_param;
shun-iwasawa 4a3868
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ParamCalculatorNode(Calculator *calculator, const TDoubleParamP ¶m,
Shinya Kitaoka 2a7129
                      std::unique_ptr<calculatornode> frame)</calculatornode>
Shinya Kitaoka 2a7129
      : CalculatorNode(calculator), m_param(param), m_frame(std::move(frame)) {
Shinya Kitaoka 120a6e
    param->addObserver(this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~ParamCalculatorNode() { m_param->removeObserver(this); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  double compute(double vars[3]) const override {
Shinya Kitaoka 120a6e
    double value      = m_param->getValue(m_frame->compute(vars) - 1);
Shinya Kitaoka 120a6e
    TMeasure *measure = m_param->getMeasure();
Shinya Kitaoka 120a6e
    if (measure) {
Shinya Kitaoka 120a6e
      const TUnit *unit = measure->getCurrentUnit();
shun-iwasawa fe2893
      if (unit) value = unit->convertTo(value);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return value;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void accept(TSyntax::CalculatorNodeVisitor &visitor) override {
shun-iwasawa 4a3868
    ParamReferenceFinder *prf = dynamic_cast<paramreferencefinder *="">(&visitor);</paramreferencefinder>
shun-iwasawa 4a3868
    if (prf) {
shun-iwasawa 4a3868
      prf->registerRefParam(m_param.getPointer());
shun-iwasawa 4a3868
      return;
shun-iwasawa 4a3868
    }
shun-iwasawa 4a3868
Shinya Kitaoka 120a6e
    ParamDependencyFinder *pdf =
Shinya Kitaoka 120a6e
        dynamic_cast<paramdependencyfinder *="">(&visitor);</paramdependencyfinder>
shun-iwasawa 4a3868
    if (pdf) {
shun-iwasawa 4a3868
      pdf->check(m_param.getPointer());
shun-iwasawa 4a3868
      if (!pdf->found()) m_param->accept(visitor);
shun-iwasawa 4a3868
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void onChange(const TParamChange ¶mChange) override {
Shinya Kitaoka 120a6e
    // The referenced parameter changed. This means the parameter owning the
Shinya Kitaoka 120a6e
    // expression this node is part of, changes too.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // A param change is thus propagated for this parameter, with the 'keyframe'
Shinya Kitaoka 120a6e
    // parameter turned off - since no keyframe value is actually altered.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (TDoubleParam *ownerParam = getCalculator()->getOwnerParameter()) {
Shinya Kitaoka 120a6e
      const std::set<tparamobserver *=""> &observers = ownerParam->observers();</tparamobserver>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TParamChange propagatedChange(ownerParam, 0, 0, false,
Shinya Kitaoka 120a6e
                                    paramChange.m_dragging,
Shinya Kitaoka 120a6e
                                    paramChange.m_undoing);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      std::set<tparamobserver *="">::const_iterator ot, oEnd = observers.end();</tparamobserver>
Shinya Kitaoka 120a6e
      for (ot = observers.begin(); ot != oEnd; ++ot)
Shinya Kitaoka 120a6e
        (*ot)->onChange(propagatedChange);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
shun-iwasawa 4a3868
shun-iwasawa 4a3868
  bool hasReference() const override { return true; }
shun-iwasawa 4a3868
};
shun-iwasawa 4a3868
shun-iwasawa 4a3868
// ParamCalculatorNode subclass to monitor referenced columns
shun-iwasawa 4a3868
class ColumnParamCalculatorNode final : public ParamCalculatorNode {
shun-iwasawa 4a3868
  int m_columnIndex;
shun-iwasawa 4a3868
shun-iwasawa 4a3868
public:
shun-iwasawa 4a3868
  ColumnParamCalculatorNode(Calculator *calculator, const TDoubleParamP ¶m,
shun-iwasawa 4a3868
                            std::unique_ptr<calculatornode> frame,</calculatornode>
shun-iwasawa 4a3868
                            int columnIndex)
shun-iwasawa 4a3868
      : ParamCalculatorNode(calculator, param, std::move(frame))
shun-iwasawa 4a3868
      , m_columnIndex(columnIndex) {}
shun-iwasawa 4a3868
shun-iwasawa 4a3868
  void accept(TSyntax::CalculatorNodeVisitor &visitor) override {
shun-iwasawa 4a3868
    ParamReferenceFinder *prf = dynamic_cast<paramreferencefinder *="">(&visitor);</paramreferencefinder>
shun-iwasawa 4a3868
    if (prf) {
shun-iwasawa 4a3868
      prf->registerRefParam(m_param.getPointer());
shun-iwasawa 4a3868
      prf->registerColumnIndex(m_columnIndex);
shun-iwasawa 4a3868
      return;
shun-iwasawa 4a3868
    }
shun-iwasawa 4a3868
shun-iwasawa 4a3868
    ParamDependencyFinder *pdf =
shun-iwasawa 4a3868
        dynamic_cast<paramdependencyfinder *="">(&visitor);</paramdependencyfinder>
shun-iwasawa 4a3868
    if (pdf) {
shun-iwasawa 4a3868
      pdf->check(m_param.getPointer());
shun-iwasawa 4a3868
      if (!pdf->found()) m_param->accept(visitor);
shun-iwasawa 4a3868
    }
shun-iwasawa 4a3868
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class XsheetDrawingCalculatorNode final : public CalculatorNode,
Shinya Kitaoka d1f6c4
                                          public boost::noncopyable {
Shinya Kitaoka 120a6e
  TXsheet *m_xsh;
Shinya Kitaoka 120a6e
  int m_columnIndex;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 2a7129
  std::unique_ptr<calculatornode> m_frame;</calculatornode>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  XsheetDrawingCalculatorNode(Calculator *calc, TXsheet *xsh, int columnIndex,
Shinya Kitaoka 2a7129
                              std::unique_ptr<calculatornode> frame)</calculatornode>
Shinya Kitaoka 120a6e
      : CalculatorNode(calc)
Shinya Kitaoka 120a6e
      , m_xsh(xsh)
Shinya Kitaoka 120a6e
      , m_columnIndex(columnIndex)
Shinya Kitaoka 2a7129
      , m_frame(std::move(frame)) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  double compute(double vars[3]) const override {
Shinya Kitaoka 120a6e
    double f = m_frame->compute(vars);
Shinya Kitaoka 120a6e
    int i    = tfloor(f);
Shinya Kitaoka 120a6e
    f        = f - (double)i;
Shinya Kitaoka 120a6e
    TXshCell cell;
Shinya Kitaoka 120a6e
    cell     = m_xsh->getCell(i, m_columnIndex);
Shinya Kitaoka 120a6e
    int d0   = cell.isEmpty() ? 0 : cell.m_frameId.getNumber();
Shinya Kitaoka 120a6e
    cell     = m_xsh->getCell(i + 1, m_columnIndex);
Shinya Kitaoka 120a6e
    int d1   = cell.isEmpty() ? 0 : cell.m_frameId.getNumber();
Shinya Kitaoka 120a6e
    double d = (1 - f) * d0 + f * d1;
Shinya Kitaoka 120a6e
    return d;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa 4a3868
  void accept(TSyntax::CalculatorNodeVisitor &visitor) override {
shun-iwasawa 4a3868
    ParamReferenceFinder *prf = dynamic_cast<paramreferencefinder *="">(&visitor);</paramreferencefinder>
shun-iwasawa 4a3868
    if (prf) prf->registerColumnIndex(m_columnIndex);
shun-iwasawa 4a3868
  }
shun-iwasawa 4a3868
shun-iwasawa 4a3868
  bool hasReference() const override { return true; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Patterns
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class XsheetReferencePattern final : public Pattern {
Shinya Kitaoka 120a6e
  TXsheet *m_xsh;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  XsheetReferencePattern(TXsheet *xsh) : m_xsh(xsh) {
Shinya Kitaoka 120a6e
    setDescription(std::string("object.action\nTransformation reference\n") +
Shinya Kitaoka 120a6e
                   "object can be: tab, table, cam<n>, camera<n>, col<n>, "</n></n></n>
Shinya Kitaoka 120a6e
                   "peg<n>, pegbar<n>\n" +</n></n>
Shinya Kitaoka 120a6e
                   "action can be: "
Shinya Kitaoka 120a6e
                   "ns,ew,rot,ang,angle,z,zdepth,sx,sy,sc,scale,scalex,scaley,"
Shinya Kitaoka 120a6e
                   "path,pos,shx,shy");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStageObjectId matchObjectName(const Token &token) const {
Shinya Kitaoka 120a6e
    std::string s = toLower(token.getText());
Shinya Kitaoka 120a6e
    int len       = (int)s.length(), i, j;
Shinya Kitaoka 120a6e
    for (i = 0; i < len && isascii(s[i]) && isalpha(s[i]); i++) {
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (i == 0) return TStageObjectId::NoneId;
Shinya Kitaoka 120a6e
    std::string a = s.substr(0, i);
Shinya Kitaoka 120a6e
    int index     = 0;
Shinya Kitaoka 120a6e
    for (j = i; j < len && isascii(s[j]) && isdigit(s[j]); j++)
Shinya Kitaoka 120a6e
      index = index * 10 + (s[j] - '0');
Shinya Kitaoka 120a6e
    if (j < len) return TStageObjectId::NoneId;
Shinya Kitaoka 120a6e
    if (i == j) index = -1;
Shinya Kitaoka 120a6e
    if ((a == "table" || a == "tab") && index < 0)
Shinya Kitaoka 120a6e
      return TStageObjectId::TableId;
Shinya Kitaoka 120a6e
    else if (a == "col" && index >= 1)
Shinya Kitaoka 120a6e
      return TStageObjectId::ColumnId(index - 1);
Shinya Kitaoka 120a6e
    else if ((a == "cam" || a == "camera") && index >= 1)
Shinya Kitaoka 120a6e
      return TStageObjectId::CameraId(index - 1);
Shinya Kitaoka 120a6e
    else if ((a == "peg" || a == "pegbar") && index >= 1)
Shinya Kitaoka 120a6e
      return TStageObjectId::PegbarId(index - 1);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return TStageObjectId::NoneId;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa 4a3868
  TStageObjectId matchExistingObjectName(const Token &token) const {
shun-iwasawa 4a3868
    TStageObjectId objId = matchObjectName(token);
shun-iwasawa 4a3868
    if (objId != TStageObjectId::NoneId &&
shun-iwasawa 4a3868
        m_xsh->getStageObjectTree()->getStageObject(objId, false))
shun-iwasawa 4a3868
      return objId;
shun-iwasawa 4a3868
    else
shun-iwasawa 4a3868
      return TStageObjectId::NoneId;
shun-iwasawa 4a3868
  }
shun-iwasawa 4a3868
Shinya Kitaoka 120a6e
  TStageObject::Channel matchChannelName(const Token &token) const {
Shinya Kitaoka 120a6e
    std::string s = toLower(token.getText());
c7649c
    if (s == "y" || s == "ns")
Shinya Kitaoka 120a6e
      return TStageObject::T_Y;
c7649c
    else if (s == "x" || s == "ew")
Shinya Kitaoka 120a6e
      return TStageObject::T_X;
Shinya Kitaoka 120a6e
    else if (s == "rot" || s == "ang" || s == "angle")
Shinya Kitaoka 120a6e
      return TStageObject::T_Angle;
Shinya Kitaoka 120a6e
    else if (s == "z" || s == "zdepth")
Shinya Kitaoka 120a6e
      return TStageObject::T_Z;
Shinya Kitaoka 120a6e
    else if (s == "sx" || s == "scalex" || s == "xscale" || s == "xs" ||
Shinya Kitaoka 120a6e
             s == "sh" || s == "scaleh" || s == "hscale" || s == "hs")
Shinya Kitaoka 120a6e
      return TStageObject::T_ScaleX;
Shinya Kitaoka 120a6e
    else if (s == "sy" || s == "scaley" || s == "yscale" || s == "ys" ||
Shinya Kitaoka 120a6e
             s == "sv" || s == "scalev" || s == "vscale" || s == "vs")
Shinya Kitaoka 120a6e
      return TStageObject::T_ScaleY;
Shinya Kitaoka 120a6e
    else if (s == "sc" || s == "scale")
Shinya Kitaoka 120a6e
      return TStageObject::T_Scale;
Shinya Kitaoka 120a6e
    else if (s == "path" || s == "pos")
Shinya Kitaoka 120a6e
      return TStageObject::T_Path;
Shinya Kitaoka 120a6e
    else if (s == "shearx" || s == "shx" || s == "shearh" || s == "shh")
Shinya Kitaoka 120a6e
      return TStageObject::T_ShearX;
Shinya Kitaoka 120a6e
    else if (s == "sheary" || s == "shy" || s == "shearv" || s == "shv")
Shinya Kitaoka 120a6e
      return TStageObject::T_ShearY;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return TStageObject::T_ChannelCount;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  bool expressionExpected(
Shinya Kitaoka 38fd86
      const std::vector<token> &previousTokens) const override {</token>
Shinya Kitaoka 120a6e
    return previousTokens.size() == 4;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool matchToken(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    int i = (int)previousTokens.size();
Shinya Kitaoka 120a6e
    if (i == 0)
shun-iwasawa 4a3868
      return matchExistingObjectName(token) != TStageObjectId::NoneId;
Rozhuk Ivan 823a31
    else if ((i == 1 && token.getText() == ".") ||
Rozhuk Ivan 823a31
             (i == 3 && token.getText() == "(") ||
Rozhuk Ivan 823a31
             (i == 5 && token.getText() == ")"))
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    else if (i == 2) {
Shinya Kitaoka 120a6e
      if (matchChannelName(token) < TStageObject::T_ChannelCount)
Shinya Kitaoka 120a6e
        return true;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        return token.getText() == "cell" &&
shun-iwasawa 4a3868
               matchExistingObjectName(previousTokens[0]).isColumn();
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool isFinished(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return previousTokens.size() >= 6;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool isComplete(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return previousTokens.size() >= 6 || previousTokens.size() == 3;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TSyntax::TokenType getTokenType(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return TSyntax::Operator;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  void getAcceptableKeywords(
Shinya Kitaoka 38fd86
      std::vector<std::string> &keywords) const override {</std::string>
Tact Yoshida 1d7cf9
    keywords.insert(keywords.end(),
Tact Yoshida 1d7cf9
                    {"table", "tab", "col", "cam", "camera", "peg", "pegbar"});
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void createNode(Calculator *calc, std::vector<calculatornode *=""> &stack,</calculatornode>
Shinya Kitaoka 473e70
                  const std::vector<token> &tokens) const override {</token>
Shinya Kitaoka 120a6e
    assert(tokens.size() >= 3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 2a7129
    std::unique_ptr<calculatornode> frameNode(</calculatornode>
Shinya Kitaoka 120a6e
        (tokens.size() == 6) ? popNode(stack)
Shinya Kitaoka 120a6e
                             : new VariableNode(calc, CalculatorNode::FRAME));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStageObjectId objectId = matchObjectName(tokens[0]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string field = toLower(tokens[2].getText());
Shinya Kitaoka 120a6e
    if (field == "cell" || field == "cel" || field == "cels") {
Shinya Kitaoka 120a6e
      int columnIndex = objectId.getIndex();
Shinya Kitaoka 2a7129
      stack.push_back(new XsheetDrawingCalculatorNode(calc, m_xsh, columnIndex,
Shinya Kitaoka 2a7129
                                                      std::move(frameNode)));
Shinya Kitaoka 120a6e
    } else {
shun-iwasawa 4a3868
      // do not create object if it does not exist
shun-iwasawa 4a3868
      TStageObject *object =
shun-iwasawa 4a3868
          m_xsh->getStageObjectTree()->getStageObject(objectId, false);
shun-iwasawa 4a3868
      if (!object) return;
Shinya Kitaoka 120a6e
      TStageObject::Channel channelName = matchChannelName(tokens[2]);
Shinya Kitaoka 120a6e
      TDoubleParam *channel             = object->getParam(channelName);
shun-iwasawa 4a3868
      if (channel) {
shun-iwasawa 4a3868
        if (objectId.isColumn())
shun-iwasawa 4a3868
          stack.push_back(new ColumnParamCalculatorNode(
shun-iwasawa 4a3868
              calc, channel, std::move(frameNode), objectId.getIndex()));
shun-iwasawa 4a3868
        else
shun-iwasawa 4a3868
          stack.push_back(
shun-iwasawa 4a3868
              new ParamCalculatorNode(calc, channel, std::move(frameNode)));
shun-iwasawa 4a3868
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class FxReferencePattern final : public Pattern {
Shinya Kitaoka 120a6e
  TXsheet *m_xsh;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FxReferencePattern(TXsheet *xsh) : m_xsh(xsh) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFx *getFx(const Token &token) const {
shun-iwasawa 4a3868
    TFx *fx =
shun-iwasawa 4a3868
        m_xsh->getFxDag()->getFxById(::to_wstring(toLower(token.getText())));
shun-iwasawa 4a3868
    // removed fx cannot be referenced
shun-iwasawa 4a3868
    if (!fx)
shun-iwasawa 4a3868
      return nullptr;
shun-iwasawa 4a3868
    else if (fx->isZerary()) {
shun-iwasawa 4a3868
      TZeraryFx *zFx = dynamic_cast<tzeraryfx *="">(fx);</tzeraryfx>
shun-iwasawa 4a3868
      // For now we cannot use zFx->getColumnFx()->getColumnIndex() < 0 to check
shun-iwasawa 4a3868
      // existence of the column. See a comment in tcolumnset.h for details.
shun-iwasawa 4a3868
      if (!zFx || !zFx->getColumnFx()->getXshColumn()->inColumnsSet())
shun-iwasawa 4a3868
        return nullptr;
shun-iwasawa 4a3868
    } else if (!m_xsh->getFxDag()->getInternalFxs()->containsFx(fx))
shun-iwasawa 4a3868
      return nullptr;
shun-iwasawa 4a3868
    return fx;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TParam *getParam(const TFx *fx, const Token &token) const {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < fx->getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
      TParam *param         = fx->getParams()->getParam(i);
Shinya Kitaoka 120a6e
      std::string paramName = ::to_string(
Shinya Kitaoka 120a6e
          TStringTable::translate(fx->getFxType() + "." + param->getName()));
shun_iwasawa b08910
      int i = paramName.find_first_of(" -");
Shinya Kitaoka 120a6e
      while (i != std::string::npos) {
Shinya Kitaoka 120a6e
        paramName.erase(i, 1);
shun_iwasawa b08910
        i = paramName.find_first_of(" -");
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      std::string paramNameToCheck = token.getText();
Shinya Kitaoka 120a6e
      if (paramName == paramNameToCheck ||
Shinya Kitaoka 120a6e
          toLower(paramName) == toLower(paramNameToCheck))
Shinya Kitaoka 120a6e
        return param;
shun-iwasawa 8cac36
shun-iwasawa 8cac36
      // in case the parameter has ui label
shun-iwasawa 8cac36
      // ( paramters of plugin fxs and intensity of GlobalControllableFx)
shun-iwasawa 8cac36
      if (param->hasUILabel()) {
shun-iwasawa 8cac36
        paramName = param->getUILabel();
shun-iwasawa 8cac36
        int i     = paramName.find_first_of(" -");
shun-iwasawa 8cac36
        while (i != std::string::npos) {
shun-iwasawa 8cac36
          paramName.erase(i, 1);
shun-iwasawa 8cac36
          i = paramName.find_first_of(" -");
shun-iwasawa 8cac36
        }
shun-iwasawa 8cac36
        if (paramName == paramNameToCheck ||
shun-iwasawa 8cac36
            toLower(paramName) == toLower(paramNameToCheck))
shun-iwasawa 8cac36
          return param;
shun-iwasawa 8cac36
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TParam *getLeafParam(const TFx *fx, const TParamSet *paramSet,
Shinya Kitaoka 120a6e
                       const Token &token) const {
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < paramSet->getParamCount(); i++) {
Shinya Kitaoka 120a6e
      TParam *param         = paramSet->getParam(i).getPointer();
Shinya Kitaoka 120a6e
      std::string paramName = param->getName();
Shinya Kitaoka 120a6e
      int i                 = paramName.find(" ");
Shinya Kitaoka 120a6e
      while (i != std::string::npos) {
Shinya Kitaoka 120a6e
        paramName.erase(i, 1);
Shinya Kitaoka 120a6e
        i = paramName.find(" ");
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      std::string paramNameToCheck = token.getText();
Shinya Kitaoka 120a6e
      if (paramName == paramNameToCheck ||
Shinya Kitaoka 120a6e
          toLower(paramName) == toLower(paramNameToCheck))
Shinya Kitaoka 120a6e
        return param;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  std::string getFirstKeyword() const override { return "fx"; }
Shinya Kitaoka 38fd86
  bool expressionExpected(
Shinya Kitaoka 38fd86
      const std::vector<token> &previousTokens) const override {</token>
Shinya Kitaoka 120a6e
    return !previousTokens.empty() && previousTokens.back().getText() == "(";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool matchToken(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    int i         = (int)previousTokens.size();
Shinya Kitaoka 120a6e
    std::string s = toLower(token.getText());
Shinya Kitaoka 120a6e
    if (i == 0 && s == "fx")
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    else if (i == 1)
Shinya Kitaoka 120a6e
      return s == ".";
Shinya Kitaoka 120a6e
    else if (i & 1) {
Shinya Kitaoka 120a6e
      if (previousTokens[i - 2].getText() == "(")
Shinya Kitaoka 120a6e
        return s == ")";
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        return s == "." || s == "(";
Shinya Kitaoka 120a6e
    } else if (i == 2) {
Shinya Kitaoka 120a6e
      // nome fx
Shinya Kitaoka 120a6e
      return getFx(token) != 0;
Shinya Kitaoka 120a6e
    } else if (i == 4) {
Shinya Kitaoka 120a6e
      TFx *fx = getFx(previousTokens[2]);
Shinya Kitaoka 120a6e
      if (!fx) return false;
Shinya Kitaoka 120a6e
      TParam *param = getParam(fx, token);
Shinya Kitaoka 120a6e
      return !!param;
Shinya Kitaoka 120a6e
    } else if (i == 6) {
Shinya Kitaoka 120a6e
      TFx *fx = getFx(previousTokens[2]);
Shinya Kitaoka 120a6e
      if (!fx) return false;
Shinya Kitaoka 120a6e
      TParam *param       = getParam(fx, previousTokens[4]);
Shinya Kitaoka 120a6e
      TParamSet *paramSet = dynamic_cast<tparamset *="">(param);</tparamset>
Shinya Kitaoka 120a6e
      if (!paramSet) return false;
Shinya Kitaoka 120a6e
      TParam *leafParam = getLeafParam(fx, paramSet, token);
Shinya Kitaoka 120a6e
      return !!param;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool isFinished(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return !previousTokens.empty() && previousTokens.back().getText() == ")";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool isComplete(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    int n = (int)previousTokens.size();
Shinya Kitaoka 120a6e
    return n >= 2 && (n & 1) == 1 && previousTokens[n - 2].getText() != "(";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TSyntax::TokenType getTokenType(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return TSyntax::Operator;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void createNode(Calculator *calc, std::vector<calculatornode *=""> &stack,</calculatornode>
Shinya Kitaoka 473e70
                  const std::vector<token> &tokens) const override {</token>
Shinya Kitaoka 120a6e
    int tokenSize = tokens.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 2a7129
    std::unique_ptr<calculatornode> frameNode(</calculatornode>
Shinya Kitaoka 120a6e
        (tokenSize > 0 && tokens.back().getText() == ")")
Shinya Kitaoka 120a6e
            ? popNode(stack)
Shinya Kitaoka 120a6e
            : new VariableNode(calc, CalculatorNode::FRAME));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TFx *fx = getFx(tokens[2]);
Shinya Kitaoka 120a6e
    if (!fx || tokenSize < 4) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TParamP param = getParam(fx, tokens[4]);
Shinya Kitaoka 120a6e
    if (!param.getPointer()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TDoubleParamP channel;
Shinya Kitaoka 120a6e
    TParamSet *paramSet = dynamic_cast<tparamset *="">(param.getPointer());</tparamset>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (paramSet && tokenSize > 6)
Shinya Kitaoka 120a6e
      channel =
Shinya Kitaoka 120a6e
          dynamic_cast<tdoubleparam *="">(getLeafParam(fx, paramSet, tokens[6]));</tdoubleparam>
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      channel = param;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (channel.getPointer())
Shinya Kitaoka 2a7129
      stack.push_back(
Shinya Kitaoka 2a7129
          new ParamCalculatorNode(calc, channel, std::move(frameNode)));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class PlasticVertexPattern final : public Pattern {
Shinya Kitaoka 120a6e
  TXsheet *m_xsh;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
Full pattern layout:
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
vertex ( columnNumber , " vertexName " ) . component (  expr )
Shinya Kitaoka 120a6e
   0   1      2       3 4      5     6 7 8     9     10  11  12
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  enum Positions {
Shinya Kitaoka 120a6e
    OBJECT,
Shinya Kitaoka 120a6e
    L1,
Shinya Kitaoka 120a6e
    COLUMN_NUMBER,
Shinya Kitaoka 120a6e
    COMMA,
Shinya Kitaoka 120a6e
    QUOTE1,
Shinya Kitaoka 120a6e
    VERTEX_NAME,
Shinya Kitaoka 120a6e
    QUOTE2,
Shinya Kitaoka 120a6e
    R1,
Shinya Kitaoka 120a6e
    SELECTOR,
Shinya Kitaoka 120a6e
    COMPONENT,
Shinya Kitaoka 120a6e
    L2,
Shinya Kitaoka 120a6e
    EXPR,
Shinya Kitaoka 120a6e
    R2,
Shinya Kitaoka 120a6e
    POSITIONS_COUNT
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PlasticVertexPattern(TXsheet *xsh) : m_xsh(xsh) {
Shinya Kitaoka 120a6e
    setDescription(
Shinya Kitaoka 120a6e
        "vertex(columnNumber, \"vertexName\").action\nVertex data\n"
Shinya Kitaoka 120a6e
        "columnNumber must be the number of the column containing the desired "
Shinya Kitaoka 120a6e
        "skeleton\n"
Shinya Kitaoka 120a6e
        "vertexName must be the name of a Plastic Skeleton vertex\n"
Shinya Kitaoka 120a6e
        "action must be one of the parameter names available for a Plastic "
Shinya Kitaoka 120a6e
        "Skeleton vertex");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  std::string getFirstKeyword() const override { return "vertex"; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  bool expressionExpected(
Shinya Kitaoka 38fd86
      const std::vector<token> &previousTokens) const override {</token>
Shinya Kitaoka 120a6e
    return (previousTokens.size() == EXPR);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool matchToken(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    struct {
Shinya Kitaoka 120a6e
      const PlasticVertexPattern *m_this;
Shinya Kitaoka 120a6e
      const SkD *skdp(const Token &columnToken) {
Shinya Kitaoka 120a6e
        int colIdx = columnToken.getIntValue() -
Shinya Kitaoka 120a6e
                     1;  // The first column (1) actually starts at index 0
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (!m_this->m_xsh->isColumnEmpty(colIdx)) {
Shinya Kitaoka 120a6e
          TStageObject *obj =
Shinya Kitaoka 120a6e
              m_this->m_xsh->getStageObject(TStageObjectId::ColumnId(colIdx));
Shinya Kitaoka 120a6e
          assert(obj);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (const SkDP &skdp = obj->getPlasticSkeletonDeformation())
Shinya Kitaoka 120a6e
            return skdp.getPointer();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        return 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } locals = {this};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const std::string &text = token.getText();
Shinya Kitaoka 120a6e
    int pos                 = previousTokens.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!m_fixedTokens[pos].empty()) return (text == m_fixedTokens[pos]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    switch (pos) {
Shinya Kitaoka 120a6e
    case COLUMN_NUMBER:
Shinya Kitaoka 120a6e
      return (token.getType() == Token::Number && locals.skdp(token));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    case VERTEX_NAME:
Shinya Kitaoka 120a6e
      if (const SkD *skdp = locals.skdp(previousTokens[COLUMN_NUMBER])) {
Shinya Kitaoka 120a6e
        const QString &vertexName = QString::fromStdString(text);
Shinya Kitaoka 120a6e
        return (skdp->vertexDeformation(vertexName) != 0);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    case COMPONENT:
Shinya Kitaoka 120a6e
      return std::count(m_components,
Shinya Kitaoka 120a6e
                        m_components + sizeof(m_components) / sizeof(Component),
Shinya Kitaoka 120a6e
                        text) > 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isFinished(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return (previousTokens.size() >= POSITIONS_COUNT);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isComplete(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return (previousTokens.size() >= POSITIONS_COUNT ||
Shinya Kitaoka 120a6e
            previousTokens.size() == L2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSyntax::TokenType getTokenType(const std::vector<token> &previousTokens,</token>
Shinya Kitaoka 473e70
                                  const Token &token) const override {
Shinya Kitaoka 120a6e
    return TSyntax::Operator;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void createNode(Calculator *calc, std::vector<calculatornode *=""> &stack,</calculatornode>
Shinya Kitaoka 473e70
                  const std::vector<token> &tokens) const override {</token>
Shinya Kitaoka 120a6e
    assert(tokens.size() > COMPONENT);
Shinya Kitaoka 120a6e
Shinya Kitaoka 2a7129
    std::unique_ptr<calculatornode> frameNode(</calculatornode>
Shinya Kitaoka 120a6e
        (tokens.size() == POSITIONS_COUNT)
Shinya Kitaoka 120a6e
            ? popNode(stack)
Shinya Kitaoka 120a6e
            : new VariableNode(calc, CalculatorNode::FRAME));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int colIdx = tokens[COLUMN_NUMBER].getIntValue() - 1;
Shinya Kitaoka 120a6e
    if (!m_xsh->isColumnEmpty(colIdx)) {
Shinya Kitaoka 120a6e
      TStageObject *obj =
Shinya Kitaoka 120a6e
          m_xsh->getStageObject(TStageObjectId::ColumnId(colIdx));
Shinya Kitaoka 120a6e
      assert(obj);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (const SkDP &skdp = obj->getPlasticSkeletonDeformation()) {
Shinya Kitaoka 120a6e
        const QString &vertexName =
Shinya Kitaoka 120a6e
            QString::fromStdString(tokens[VERTEX_NAME].getText());
Shinya Kitaoka 120a6e
        if (SkVD *skvd = skdp->vertexDeformation(vertexName)) {
shun-iwasawa fe2893
          const Component *componentsEnd = m_components + sizeof(m_components) /
shun-iwasawa fe2893
                                                              sizeof(Component),
Shinya Kitaoka 120a6e
                          *component = std::find(m_components, componentsEnd,
Shinya Kitaoka 120a6e
                                                 tokens[COMPONENT].getText());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (component != componentsEnd) {
Shinya Kitaoka 120a6e
            const TDoubleParamP ¶m =
Shinya Kitaoka 120a6e
                skvd->m_params[component->m_paramId].getPointer();
Shinya Kitaoka 2a7129
            stack.push_back(
Shinya Kitaoka 2a7129
                new ParamCalculatorNode(calc, param, std::move(frameNode)));
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  struct Component {
Shinya Kitaoka 120a6e
    std::string m_name;
Shinya Kitaoka 120a6e
    SkVD::Params m_paramId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bool operator==(const std::string &name) const { return (m_name == name); }
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  static const std::string m_fixedTokens[POSITIONS_COUNT];
Shinya Kitaoka 120a6e
  static const Component m_components[5];
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const std::string PlasticVertexPattern::m_fixedTokens[POSITIONS_COUNT] = {
Shinya Kitaoka 120a6e
    "vertex", "(", "", ",", "\"", "", "\"", ")", ".", "", "(", "", ")"};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const PlasticVertexPattern::Component PlasticVertexPattern::m_components[] = {
Shinya Kitaoka 120a6e
    {"ang", SkVD::ANGLE},
Shinya Kitaoka 120a6e
    {"angle", SkVD::ANGLE},
Shinya Kitaoka 120a6e
    {"dist", SkVD::DISTANCE},
Shinya Kitaoka 120a6e
    {"distance", SkVD::DISTANCE},
Shinya Kitaoka 120a6e
    {"so", SkVD::SO}};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
//    API functions
Toshihiro Shimizu 890ddd
//******************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSyntax::Grammar *createXsheetGrammar(TXsheet *xsh) {
Shinya Kitaoka 120a6e
  Grammar *grammar = new Grammar();
Shinya Kitaoka 120a6e
  grammar->addPattern(new XsheetReferencePattern(xsh));
Shinya Kitaoka 120a6e
  grammar->addPattern(new FxReferencePattern(xsh));
Shinya Kitaoka 120a6e
  grammar->addPattern(new PlasticVertexPattern(xsh));
Shinya Kitaoka 120a6e
  return grammar;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool dependsOn(TExpression &expr, TDoubleParam *possiblyDependentParam) {
Shinya Kitaoka 120a6e
  ParamDependencyFinder pdf(possiblyDependentParam);
Shinya Kitaoka 120a6e
  expr.accept(pdf);
Shinya Kitaoka 120a6e
  return pdf.found();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool dependsOn(TDoubleParam *param, TDoubleParam *possiblyDependentParam) {
Shinya Kitaoka 120a6e
  ParamDependencyFinder pdf(possiblyDependentParam);
Shinya Kitaoka 120a6e
  param->accept(pdf);
Shinya Kitaoka 120a6e
  return pdf.found();
Toshihiro Shimizu 890ddd
}
shun-iwasawa 4a3868
shun-iwasawa 4a3868
void referenceParams(TExpression &expr, QSet<int> &columnIndices,</int>
shun-iwasawa 4a3868
                     QSet<tdoubleparam *=""> ¶ms) {</tdoubleparam>
shun-iwasawa 4a3868
  ParamReferenceFinder prf;
shun-iwasawa 4a3868
  expr.accept(prf);
shun-iwasawa 4a3868
  columnIndices = prf.columnIndices();
shun-iwasawa 4a3868
  params        = prf.refParams();
shun-iwasawa 4a3868
}