Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TELLIPTIC_BRUSH_P_H
Toshihiro Shimizu 890ddd
#define TELLIPTIC_BRUSH_P_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Shinya Kitaoka 120a6e
#include "tgl.h"  //tglPixelSize
Toshihiro Shimizu 890ddd
#include "tstrokeoutline.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tellipticbrush {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Tolerance parameter used somewhere throughout this code.
Toshihiro Shimizu 890ddd
const double tolPar = 1e-6;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Geometric Helper Functions
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double dist(const TPointD &P1, const TPointD &P2);
Toshihiro Shimizu 890ddd
double dist(const TThickPoint &P1, const TThickPoint &P2);
Toshihiro Shimizu 890ddd
double angle(const TPointD &v1, const TPointD &v2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD intersectionCoords(const TPointD &P0, const TPointD &d0,
Shinya Kitaoka 120a6e
                           const TPointD &P1, const TPointD &d1,
Shinya Kitaoka 120a6e
                           double detTol = 1e-2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void buildEnvelopeDirection(const TThickPoint &p, const TThickPoint &d,
Shinya Kitaoka 120a6e
                            bool left, TPointD &res);
Shinya Kitaoka 120a6e
void buildEnvelopeDirections(const TThickPoint &p, const TThickPoint &d,
Shinya Kitaoka 120a6e
                             TPointD &resL, TPointD &resR);
Shinya Kitaoka 120a6e
void buildEnvelopeVector(const TThickPoint &p, const TThickPoint &d, bool left,
Shinya Kitaoka 120a6e
                         TPointD &res);
Shinya Kitaoka 120a6e
void buildEnvelopeVectors(const TThickPoint &p, const TThickPoint &d,
Shinya Kitaoka 120a6e
                          TPointD &resL, TPointD &resR);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void buildAngularSubdivision(double radius, double angle, double err,
Shinya Kitaoka 120a6e
                             int &nAngles);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD computeBBox(const TStroke &stroke);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Options structure
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
  Structure needed to hold both external and internal outlinization parameters.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
struct OutlinizationData {
Shinya Kitaoka 120a6e
  TOutlineUtil::OutlineParameter m_options;
Shinya Kitaoka 120a6e
  double m_pixSize;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  OutlinizationData() : m_options(), m_pixSize(0.0) {}
Shinya Kitaoka 120a6e
  OutlinizationData(const TOutlineUtil::OutlineParameter &options)
Shinya Kitaoka 120a6e
      : m_options(options), m_pixSize(sqrt(tglGetPixelSize2())) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Centerline Point struct
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  CenterlinePoint contains the data a about a discretized centerline stroke
Shinya Kitaoka 120a6e
  point -
Toshihiro Shimizu 890ddd
  which includes its position, and eventual forward and backward derivative-like
Toshihiro Shimizu 890ddd
  directions. Thickness data is included in the structure.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  These informations are necessary and sufficient to build associated outline
Shinya Kitaoka 120a6e
  points,
Toshihiro Shimizu 890ddd
  and eventual additional points related to caps.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
struct CenterlinePoint {
Shinya Kitaoka 120a6e
  int m_chunkIdx;  //!< The quadratic chunk index containing this point
Shinya Kitaoka 120a6e
  double m_t;      //!< The quadratic parameter where this point can be found
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickPoint m_p;  //!< The point's thick coordinates
Shinya Kitaoka 120a6e
  bool m_posBuilt;  //!< Wheteher m_p has been calculated
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickPoint m_prevD;  //!< The backward direction
Shinya Kitaoka 120a6e
  bool m_hasPrevD;      //!< If the point has (envelopable) backward direction
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickPoint m_nextD;  //!< The forward direction
Shinya Kitaoka 120a6e
  bool m_hasNextD;      //!< If the point has (envelopable) forward direction
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_dirsBuilt;  //!< Whether directions have been calculated
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_covered;  //!< Whether this point's outline can't be seen
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_countIdx;  //!< Additional index needed by some procedural style...
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  CenterlinePoint() : m_chunkIdx(-1), m_posBuilt(false), m_dirsBuilt(false) {}
Shinya Kitaoka 120a6e
  CenterlinePoint(int chunk, double t)
Shinya Kitaoka 120a6e
      : m_chunkIdx(chunk)
Shinya Kitaoka 120a6e
      , m_t(t)
Shinya Kitaoka 120a6e
      , m_posBuilt(false)
Shinya Kitaoka 120a6e
      , m_dirsBuilt(false)
Shinya Kitaoka 120a6e
      , m_countIdx(0) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~CenterlinePoint() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void buildPos(const TStroke &stroke);
Shinya Kitaoka 120a6e
  void buildDirs(const TStroke &stroke);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool operator<(const CenterlinePoint &cp) const {
Shinya Kitaoka 120a6e
    return m_chunkIdx < cp.m_chunkIdx
Shinya Kitaoka 120a6e
               ? true
Shinya Kitaoka 120a6e
               : m_chunkIdx > cp.m_chunkIdx ? false : m_t < cp.m_t;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Linearizator Classes
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  The StrokeLinearizator class models a stroke linearization interface that
Toshihiro Shimizu 890ddd
  extracts points of interest from a succession of stroke quadratics.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
class StrokeLinearizator {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  const TStroke *m_stroke;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  StrokeLinearizator(const TStroke *stroke) : m_stroke(stroke) {}
Shinya Kitaoka 120a6e
  virtual ~StrokeLinearizator() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
Adds interesting stroke points to be discretized in the
Shinya Kitaoka 120a6e
chunk-th TThickQuadratic stroke.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
\note The initial point (P0) of the quadratic is always added by the
Shinya Kitaoka 120a6e
outlinization algorithm before these linearization functions are invoked
Shinya Kitaoka 120a6e
(whereas P2 belongs to the next quadratic).
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  virtual void linearize(std::vector<centerlinepoint> &cPoints, int chunk) = 0;</centerlinepoint>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Outline Builder classes
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  The OutlineBuilder class is the object used to translate centerline points
Toshihiro Shimizu 890ddd
  into outline points. The purpose of this class is to take a CenterlinePoint
Toshihiro Shimizu 890ddd
  instance and build a couple of outline points - at either side of the
Toshihiro Shimizu 890ddd
  centerline - eventually adding (cap) points to form a smooth outline.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
class OutlineBuilder {
Shinya Kitaoka 120a6e
  double m_pixSize;
Shinya Kitaoka 120a6e
  TStroke::OutlineOptions m_oOptions;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_lastChunk;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  typedef void (OutlineBuilder::*OutlineBuilderFunc)(
Shinya Kitaoka 120a6e
      std::vector<toutlinepoint> &outPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  OutlineBuilderFunc m_addBeginCap;
Shinya Kitaoka 120a6e
  OutlineBuilderFunc m_addEndCap;
Shinya Kitaoka 120a6e
  OutlineBuilderFunc m_addSideCaps;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typedef void (OutlineBuilder::*BBoxBuilderFunc)(
Shinya Kitaoka 120a6e
      TRectD &bbox, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  BBoxBuilderFunc m_addBeginCap_ext;
Shinya Kitaoka 120a6e
  BBoxBuilderFunc m_addEndCap_ext;
Shinya Kitaoka 120a6e
  BBoxBuilderFunc m_addSideCaps_ext;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
Type-specific outline container functions.
Shinya Kitaoka 120a6e
Used with outline building sub-routines that may be used to supply
Shinya Kitaoka 120a6e
different outline container types.
Shinya Kitaoka 120a6e
For example, a TRectD may be considered a container class to be used
Shinya Kitaoka 120a6e
when building the outline bbox.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  template <typename t=""></typename>
Shinya Kitaoka 120a6e
  void addEnvelopePoint(T &container, const TPointD &oPoint, int countIdx = 0);
Shinya Kitaoka 120a6e
  template <typename t=""></typename>
Shinya Kitaoka 120a6e
  void addExtensionPoint(T &container, const TPointD &oPoint, int countIdx = 0);
Shinya Kitaoka 120a6e
  template <typename t=""></typename>
Shinya Kitaoka 120a6e
  void addOutlineBuilderFunc(OutlineBuilder::OutlineBuilderFunc func,
Shinya Kitaoka 120a6e
                             T &container, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  OutlineBuilder(const OutlinizationData &data, const TStroke &stroke);
Shinya Kitaoka 120a6e
  ~OutlineBuilder() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
Transforms the specified centerline point into outline points, and adds them to
Shinya Kitaoka 120a6e
the supplied outline points vector.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  void buildOutlinePoints(std::vector<toutlinepoint> &outPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                          const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void buildOutlineExtensions(TRectD &bbox, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  void addCircle(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                 const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
  void addCircularArcPoints(int idx, std::vector<toutlinepoint> &outPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                            const TPointD ¢er, const TPointD &ray,
Shinya Kitaoka 120a6e
                            double angle, int nAngles, int countIdx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addRoundBeginCap(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                        const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
  void addRoundEndCap(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                      const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addButtBeginCap(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                       const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
  void addButtEndCap(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                     const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  template <typename t=""></typename>
Shinya Kitaoka 120a6e
  void addProjectingBeginCap(T &oPoints, const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
  template <typename t=""></typename>
Shinya Kitaoka 120a6e
  void addProjectingEndCap(T &oPoints, const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addRoundSideCaps(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                        const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
  void addBevelSideCaps(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Shinya Kitaoka 120a6e
                        const CenterlinePoint &cPoint);
Shinya Kitaoka 120a6e
  template <typename t=""></typename>
Shinya Kitaoka 120a6e
  void addMiterSideCaps(T &oPoints, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Explicit specializations of OutlineBuilder's methods
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Container of Outline Points (for common outline extraction)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline void OutlineBuilder::addEnvelopePoint(
Shinya Kitaoka 120a6e
    std::vector<toutlinepoint> &oPoints, const TPointD &oPoint, int countIdx) {</toutlinepoint>
Shinya Kitaoka 120a6e
  oPoints.push_back(TOutlinePoint(oPoint, countIdx));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline void OutlineBuilder::addExtensionPoint(
Shinya Kitaoka 120a6e
    std::vector<toutlinepoint> &oPoints, const TPointD &oPoint, int countIdx) {</toutlinepoint>
Shinya Kitaoka 120a6e
  oPoints.push_back(TOutlinePoint(oPoint, countIdx));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addOutlineBuilderFunc(
Shinya Kitaoka 120a6e
    OutlineBuilder::OutlineBuilderFunc func,
Shinya Kitaoka 120a6e
    std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint) {</toutlinepoint>
Shinya Kitaoka 120a6e
  (this->*func)(oPoints, cPoint);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Rect (for bounding box extraction)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline void OutlineBuilder::addEnvelopePoint(TRectD &bbox,
Shinya Kitaoka 120a6e
                                             const TPointD &oPoint,
Shinya Kitaoka 120a6e
                                             int countIdx) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline void OutlineBuilder::addExtensionPoint(TRectD &bbox,
Shinya Kitaoka 120a6e
                                              const TPointD &oPoint,
Shinya Kitaoka 120a6e
                                              int countIdx) {
Shinya Kitaoka 120a6e
  bbox.x0 = std::min(bbox.x0, oPoint.x);
Shinya Kitaoka 120a6e
  bbox.y0 = std::min(bbox.y0, oPoint.y);
Shinya Kitaoka 120a6e
  bbox.x1 = std::max(bbox.x1, oPoint.x);
Shinya Kitaoka 120a6e
  bbox.y1 = std::max(bbox.y1, oPoint.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addOutlineBuilderFunc(
Shinya Kitaoka 120a6e
    OutlineBuilder::OutlineBuilderFunc func, TRectD &container,
Shinya Kitaoka 120a6e
    const CenterlinePoint &cPoint) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Standard Outline Builder (from Centerline Points)
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void buildOutline(const TStroke &stroke, std::vector<centerlinepoint> &cPoints,</centerlinepoint>
Shinya Kitaoka 120a6e
                  TStrokeOutline &outline, const OutlinizationData &data);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tellipticbrush
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TELLIPTIC_BRUSH_P_H