Toshihiro Shimizu 890ddd
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"
Toshihiro Shimizu 890ddd
#include "tgl.h" //tglPixelSize
Toshihiro Shimizu 890ddd
#include "tstrokeoutline.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tellipticbrush
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!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
Toshihiro Shimizu 890ddd
TPointD intersectionCoords(const TPointD &P0, const TPointD &d0, const TPointD &P1, const TPointD &d1,
Toshihiro Shimizu 890ddd
						   double detTol = 1e-2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void buildEnvelopeDirection(const TThickPoint &p, const TThickPoint &d, bool left, TPointD &res);
Toshihiro Shimizu 890ddd
void buildEnvelopeDirections(const TThickPoint &p, const TThickPoint &d, TPointD &resL, TPointD &resR);
Toshihiro Shimizu 890ddd
void buildEnvelopeVector(const TThickPoint &p, const TThickPoint &d, bool left, TPointD &res);
Toshihiro Shimizu 890ddd
void buildEnvelopeVectors(const TThickPoint &p, const TThickPoint &d, TPointD &resL, TPointD &resR);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void buildAngularSubdivision(double radius, double angle, double err, 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 {
Toshihiro Shimizu 890ddd
	TOutlineUtil::OutlineParameter m_options;
Toshihiro Shimizu 890ddd
	double m_pixSize;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OutlinizationData() : m_options(), m_pixSize(0.0) {}
Toshihiro Shimizu 890ddd
	OutlinizationData(const TOutlineUtil::OutlineParameter &options)
Toshihiro Shimizu 890ddd
		: m_options(options), m_pixSize(sqrt(tglGetPixelSize2()))
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Centerline Point struct
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  CenterlinePoint contains the data a about a discretized centerline stroke 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
Toshihiro Shimizu 890ddd
  These informations are necessary and sufficient to build associated outline points,
Toshihiro Shimizu 890ddd
  and eventual additional points related to caps.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
struct CenterlinePoint {
Toshihiro Shimizu 890ddd
	int m_chunkIdx; //!< The quadratic chunk index containing this point
Toshihiro Shimizu 890ddd
	double m_t;		//!< The quadratic parameter where this point can be found
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TThickPoint m_p; //!< The point's thick coordinates
Toshihiro Shimizu 890ddd
	bool m_posBuilt; //!< Wheteher m_p has been calculated
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TThickPoint m_prevD; //!< The backward direction
Toshihiro Shimizu 890ddd
	bool m_hasPrevD;	 //!< If the point has (envelopable) backward direction
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TThickPoint m_nextD; //!< The forward direction
Toshihiro Shimizu 890ddd
	bool m_hasNextD;	 //!< If the point has (envelopable) forward direction
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_dirsBuilt; //!< Whether directions have been calculated
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_covered; //!< Whether this point's outline can't be seen
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_countIdx; //!< Additional index needed by some procedural style...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CenterlinePoint() : m_chunkIdx(-1), m_posBuilt(false), m_dirsBuilt(false) {}
Toshihiro Shimizu 890ddd
	CenterlinePoint(int chunk, double t) : m_chunkIdx(chunk), m_t(t), m_posBuilt(false), m_dirsBuilt(false), m_countIdx(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~CenterlinePoint() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void buildPos(const TStroke &stroke);
Toshihiro Shimizu 890ddd
	void buildDirs(const TStroke &stroke);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool operator<(const CenterlinePoint &cp) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return m_chunkIdx < cp.m_chunkIdx ? true : m_chunkIdx > cp.m_chunkIdx ? false : m_t < cp.m_t;
Toshihiro Shimizu 890ddd
	}
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
*/
Toshihiro Shimizu 890ddd
class StrokeLinearizator
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	const TStroke *m_stroke;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	StrokeLinearizator(const TStroke *stroke) : m_stroke(stroke) {}
Toshihiro Shimizu 890ddd
	virtual ~StrokeLinearizator() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*!
Toshihiro Shimizu 890ddd
    Adds interesting stroke points to be discretized in the
Toshihiro Shimizu 890ddd
    chunk-th TThickQuadratic stroke.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    \note The initial point (P0) of the quadratic is always added by the
Toshihiro Shimizu 890ddd
    outlinization algorithm before these linearization functions are invoked
Toshihiro Shimizu 890ddd
    (whereas P2 belongs to the next quadratic).
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	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
*/
Toshihiro Shimizu 890ddd
class OutlineBuilder
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double m_pixSize;
Toshihiro Shimizu 890ddd
	TStroke::OutlineOptions m_oOptions;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_lastChunk;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	typedef void (OutlineBuilder::*OutlineBuilderFunc)(
Toshihiro Shimizu 890ddd
		std::vector<toutlinepoint> &outPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	OutlineBuilderFunc m_addBeginCap;
Toshihiro Shimizu 890ddd
	OutlineBuilderFunc m_addEndCap;
Toshihiro Shimizu 890ddd
	OutlineBuilderFunc m_addSideCaps;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	typedef void (OutlineBuilder::*BBoxBuilderFunc)(
Toshihiro Shimizu 890ddd
		TRectD &bbox, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	BBoxBuilderFunc m_addBeginCap_ext;
Toshihiro Shimizu 890ddd
	BBoxBuilderFunc m_addEndCap_ext;
Toshihiro Shimizu 890ddd
	BBoxBuilderFunc m_addSideCaps_ext;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
    Type-specific outline container functions.
Toshihiro Shimizu 890ddd
    Used with outline building sub-routines that may be used to supply
Toshihiro Shimizu 890ddd
    different outline container types.
Toshihiro Shimizu 890ddd
    For example, a TRectD may be considered a container class to be used
Toshihiro Shimizu 890ddd
    when building the outline bbox.
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	template <typename t=""></typename>
Toshihiro Shimizu 890ddd
	void addEnvelopePoint(T &container, const TPointD &oPoint, int countIdx = 0);
Toshihiro Shimizu 890ddd
	template <typename t=""></typename>
Toshihiro Shimizu 890ddd
	void addExtensionPoint(T &container, const TPointD &oPoint, int countIdx = 0);
Toshihiro Shimizu 890ddd
	template <typename t=""></typename>
Toshihiro Shimizu 890ddd
	void addOutlineBuilderFunc(OutlineBuilder::OutlineBuilderFunc func,
Toshihiro Shimizu 890ddd
							   T &container, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	OutlineBuilder(const OutlinizationData &data, const TStroke &stroke);
Toshihiro Shimizu 890ddd
	~OutlineBuilder() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*!
Toshihiro Shimizu 890ddd
    Transforms the specified centerline point into outline points, and adds them to
Toshihiro Shimizu 890ddd
    the supplied outline points vector.
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	void buildOutlinePoints(
Toshihiro Shimizu 890ddd
		std::vector<toutlinepoint> &outPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void buildOutlineExtensions(TRectD &bbox, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	void addCircle(std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
	void addCircularArcPoints(
Toshihiro Shimizu 890ddd
		int idx, std::vector<toutlinepoint> &outPoints,</toutlinepoint>
Toshihiro Shimizu 890ddd
		const TPointD ¢er, const TPointD &ray, double angle, int nAngles,
Toshihiro Shimizu 890ddd
		int countIdx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addRoundBeginCap(std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
	void addRoundEndCap(std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addButtBeginCap(std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
	void addButtEndCap(std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	template <typename t=""></typename>
Toshihiro Shimizu 890ddd
	void addProjectingBeginCap(T &oPoints, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
	template <typename t=""></typename>
Toshihiro Shimizu 890ddd
	void addProjectingEndCap(T &oPoints, const CenterlinePoint &cPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addRoundSideCaps(std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
	void addBevelSideCaps(std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint);</toutlinepoint>
Toshihiro Shimizu 890ddd
	template <typename t=""></typename>
Toshihiro Shimizu 890ddd
	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 <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addEnvelopePoint(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Toshihiro Shimizu 890ddd
											 const TPointD &oPoint, int countIdx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	oPoints.push_back(TOutlinePoint(oPoint, countIdx));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addExtensionPoint(std::vector<toutlinepoint> &oPoints,</toutlinepoint>
Toshihiro Shimizu 890ddd
											  const TPointD &oPoint, int countIdx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	oPoints.push_back(TOutlinePoint(oPoint, countIdx));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addOutlineBuilderFunc(
Toshihiro Shimizu 890ddd
	OutlineBuilder::OutlineBuilderFunc func,
Toshihiro Shimizu 890ddd
	std::vector<toutlinepoint> &oPoints, const CenterlinePoint &cPoint)</toutlinepoint>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	(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 <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addEnvelopePoint(TRectD &bbox, const TPointD &oPoint, int countIdx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addExtensionPoint(TRectD &bbox, const TPointD &oPoint, int countIdx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bbox.x0 = tmin(bbox.x0, oPoint.x);
Toshihiro Shimizu 890ddd
	bbox.y0 = tmin(bbox.y0, oPoint.y);
Toshihiro Shimizu 890ddd
	bbox.x1 = tmax(bbox.x1, oPoint.x);
Toshihiro Shimizu 890ddd
	bbox.y1 = tmax(bbox.y1, oPoint.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
inline void OutlineBuilder::addOutlineBuilderFunc(
Toshihiro Shimizu 890ddd
	OutlineBuilder::OutlineBuilderFunc func,
Toshihiro Shimizu 890ddd
	TRectD &container, const CenterlinePoint &cPoint)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
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>
Toshihiro Shimizu 890ddd
				  TStrokeOutline &outline, const OutlinizationData &data);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace tellipticbrush
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //TELLIPTIC_BRUSH_P_H