da847a
da847a
da847a
// TnzTools includes
da847a
#include <tools replicator.h=""></tools>
da847a
#include <tools modifierjitter.h="" modifiers=""></tools>
da847a
da847a
da847a
// TnzCore includes
da847a
#include <tgl.h></tgl.h>
da847a
da847a
da847a
//*****************************************************************************************
da847a
//    TReplicatorJitter implementation
da847a
//*****************************************************************************************
da847a
da847a
class TReplicatorJitter final : public TReplicator {
da847a
  Q_DECLARE_TR_FUNCTIONS(TReplicatorJitter)
da847a
public:
da847a
  const TStringId m_idPeriod;
da847a
  const TStringId m_idAmplitude;
1eb7c9
  const TStringId m_idKeepFirstPoint;
1eb7c9
  const TStringId m_idKeepLastPoint;
da847a
da847a
protected:
da847a
  TAssistantPoint &m_center;
da847a
da847a
public:
da847a
  TReplicatorJitter(TMetaObject &object):
da847a
    TReplicator(object),
da847a
    m_idPeriod("period"),
1eb7c9
    m_idAmplitude("amplitude"),
1eb7c9
    m_idKeepFirstPoint("keepFirstPoint"),
1eb7c9
    m_idKeepLastPoint("keepLastPoint"),
da847a
    m_center( addPoint("center", TAssistantPoint::CircleCross) )
da847a
  {
da847a
    TDoubleProperty *p;
da847a
    
da847a
    p = new TDoubleProperty(m_idPeriod.str(), 0.0, 1000, getPeriod());
da847a
    p->setNonLinearSlider();
da847a
    addProperty(p);
da847a
da847a
    p = new TDoubleProperty(m_idAmplitude.str(), 0.0, 1000, getAmplitude());
da847a
    p->setNonLinearSlider();
da847a
    addProperty(p);
1eb7c9
    
1eb7c9
    addProperty( new TBoolProperty(m_idKeepFirstPoint.str(), getKeepFirstPoint()) );
1eb7c9
    addProperty( new TBoolProperty(m_idKeepLastPoint.str(), getKeepLastPoint()) );
da847a
  }
da847a
da847a
  
da847a
  static QString getLocalName()
da847a
    { return tr("Jitter"); }
da847a
da847a
    
da847a
  void updateTranslation() const override {
da847a
    TReplicator::updateTranslation();
da847a
    setTranslation(m_idPeriod, tr("Period"));
da847a
    setTranslation(m_idAmplitude, tr("Amplitude"));
1eb7c9
    setTranslation(m_idKeepFirstPoint, tr("Fix First Point"));
1eb7c9
    setTranslation(m_idKeepLastPoint, tr("Fix Last Point"));
da847a
  }
da847a
da847a
  
da847a
  inline double getPeriod() const
da847a
    { return data()[m_idPeriod].getDouble(); }
da847a
  inline double getAmplitude() const
da847a
    { return data()[m_idAmplitude].getDouble(); }
1eb7c9
  inline bool getKeepFirstPoint() const
1eb7c9
    { return data()[m_idKeepFirstPoint].getBool(); }
1eb7c9
  inline bool getKeepLastPoint() const
1eb7c9
    { return data()[m_idKeepLastPoint].getBool(); }
da847a
da847a
protected:
da847a
  inline void setPeriod(double x)
da847a
    { if (getPeriod() != x) data()[m_idPeriod].setDouble(x); }
da847a
  inline void setAmplitude(double x)
da847a
    { if (getAmplitude() != x) data()[m_idAmplitude].setDouble(x); }
da847a
da847a
    
da847a
  void onSetDefaults() override {
da847a
    setPeriod(30);
da847a
    setAmplitude(10);
da847a
    TReplicator::onSetDefaults();
da847a
  }
da847a
da847a
  
da847a
  void onFixData() override {
da847a
    TReplicator::onFixData();
da847a
    setPeriod( std::max(0.0, std::min(1000.0, getPeriod())) );
da847a
    setAmplitude( std::max(0.0, std::min(1000.0, getAmplitude())) );
da847a
  }
da847a
da847a
  
da847a
  double getScale(const TAffine &a) const {
da847a
    return sqrt( a.a11*a.a11 + a.a12*a.a12
da847a
               + a.a21*a.a21 + a.a22*a.a22 )/2;
da847a
  }
da847a
    
da847a
public:
da847a
  
da847a
  void getPoints(const TAffine &toTool, PointList &points) const override {
18450b
    int pointsCount = (int)points.size();
18450b
    int i0 = getSkipFirst();
18450b
    int i1 = pointsCount - getSkipLast();
18450b
    if (i0 < 0) i0 = 0;
18450b
    if (i1 > pointsCount) i1 = pointsCount;
18450b
    if (i0 >= i1) return;
da847a
    
da847a
    double scale = getScale(toTool);
da847a
    double period = getPeriod()*scale;
da847a
    double amplitude = getAmplitude()*scale;
18450b
    if (period > TConsts::epsilon && amplitude > TConsts::epsilon) {
da847a
      int seedX = 0;
da847a
      int seedY = 7722441;
18450b
      for(int i = i0; i < i1; ++i) {
1eb7c9
        points[i].x += TModifierJitter::func(seedX, points[i].x/period)*amplitude;
1eb7c9
        points[i].y += TModifierJitter::func(seedY, points[i].y/period)*amplitude;
da847a
        ++seedX, ++seedY;
da847a
      }
da847a
    }
da847a
  }
da847a
  
da847a
  
da847a
  void getModifiers(
da847a
    const TAffine &toTool,
da847a
    TInputModifier::List &outModifiers ) const override
da847a
  {
da847a
    double scale = getScale(toTool);
da847a
    outModifiers.push_back(new TModifierJitter(
da847a
      getPeriod()*scale,
da847a
      getAmplitude()*scale,
18450b
      getSkipFirst(),
1eb7c9
      getSkipLast(),
1eb7c9
      getKeepFirstPoint(),
1eb7c9
      getKeepLastPoint() ));
da847a
  }
da847a
da847a
  
da847a
  void draw(TToolViewer*, bool enabled) const override {
da847a
    double alpha = getDrawingAlpha(enabled);
da847a
    double pixelSize = sqrt(tglGetPixelSize2());
da847a
    
da847a
    TPointD c = m_center.position;
da847a
    double h = getPeriod()/2;
da847a
    double q = h/2;
da847a
    double a = getAmplitude();
da847a
    
da847a
    drawSegment(TPointD(c.x-h, c.y  ), TPointD(c.x-q, c.y+a), pixelSize, alpha);
da847a
    drawSegment(TPointD(c.x-q, c.y+a), TPointD(c.x+q, c.y-a), pixelSize, alpha);
da847a
    drawSegment(TPointD(c.x+q, c.y-a), TPointD(c.x+h, c.y  ), pixelSize, alpha);
da847a
  }
da847a
};
da847a
da847a
da847a
//*****************************************************************************************
da847a
//    Registration
da847a
//*****************************************************************************************
da847a
da847a
static TAssistantTypeT<treplicatorjitter> replicatorJitter("replicatorJitter");</treplicatorjitter>