Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tregionprop.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
//#include "tcurves.h"
Toshihiro Shimizu 890ddd
//#include "tgl.h"
Toshihiro Shimizu 890ddd
//#include "tcolorfunctions.h"
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
//#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tsimplecolorstyles.h"
Toshihiro Shimizu 890ddd
//#include "tcurveutil.h"
Toshihiro Shimizu 890ddd
//#include "tdebugmessage.h"
Toshihiro Shimizu 890ddd
//#include "tflash.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifndef _WIN32
Toshihiro Shimizu 890ddd
#define CALLBACK
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRegionProp::TRegionProp(const TRegion *region)
Toshihiro Shimizu 890ddd
	: m_region(region), m_regionChanged(true)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool computeOutline(const TRegion *region,
Toshihiro Shimizu 890ddd
					TRegionOutline::PointVector &polyline,
Toshihiro Shimizu 890ddd
					const double pixelSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bool doAntialiasing = false;
Toshihiro Shimizu 890ddd
	polyline.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<tpointd> polyline2d;</tpointd>
Toshihiro Shimizu 890ddd
	vector<int> indices;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, edgeSize = region->getEdgeCount(), oldSize = 0;
Toshihiro Shimizu 890ddd
	for (i = 0; i < edgeSize; i++) {
Toshihiro Shimizu 890ddd
		TEdge &edge = *region->getEdge(i);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (edge.m_index >= 0 && edge.m_s) {
Toshihiro Shimizu 890ddd
			bool outline = (edge.m_s->getAverageThickness() == 0.0);
Toshihiro Shimizu 890ddd
			if (outline && !doAntialiasing) {
Toshihiro Shimizu 890ddd
				//The region must be antialiased if it has at least one invisible (0-thin) edge
Toshihiro Shimizu 890ddd
				doAntialiasing = true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//Plus, edges will have to be reproduced independently from the edge side
Toshihiro Shimizu 890ddd
				indices.reserve(edgeSize);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (outline && (edge.m_w0 > edge.m_w1)) {
Toshihiro Shimizu 890ddd
				int newSize = polyline2d.size();
Toshihiro Shimizu 890ddd
				if (oldSize < newSize) {
Toshihiro Shimizu 890ddd
					//There is a sequence of forward vertices
Toshihiro Shimizu 890ddd
					indices.push_back(newSize - oldSize);
Toshihiro Shimizu 890ddd
					oldSize = newSize;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				stroke2polyline(polyline2d, *edge.m_s, pixelSize, edge.m_w1, edge.m_w0, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//Insert the sequence of backward vertices
Toshihiro Shimizu 890ddd
				newSize = polyline2d.size();
Toshihiro Shimizu 890ddd
				indices.push_back(oldSize - newSize);
Toshihiro Shimizu 890ddd
				oldSize = newSize;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				stroke2polyline(polyline2d, *edge.m_s, pixelSize, edge.m_w0, edge.m_w1);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Copy points to the output
Toshihiro Shimizu 890ddd
	int pointNumber = polyline2d.size();
Toshihiro Shimizu 890ddd
	polyline.reserve(pointNumber);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int j, k, l, indicesCount = indices.size();
Toshihiro Shimizu 890ddd
	for (i = 0, k = 0; k < indicesCount; ++k) {
Toshihiro Shimizu 890ddd
		l = indices[k];
Toshihiro Shimizu 890ddd
		if (l == 0)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (l > 0) {
Toshihiro Shimizu 890ddd
			l = i + l;
Toshihiro Shimizu 890ddd
			for (j = i; j < l; ++j)
Toshihiro Shimizu 890ddd
				polyline.push_back(T3DPointD(polyline2d[j], 0.0));
Toshihiro Shimizu 890ddd
			i = l;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			l = i - l;
Toshihiro Shimizu 890ddd
			j = l - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Inverted sequences are symmetric by construction.
Toshihiro Shimizu 890ddd
			//If necessary, chop the last element.
Toshihiro Shimizu 890ddd
			if (polyline2d[i] == polyline2d[j])
Toshihiro Shimizu 890ddd
				++i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (; j >= i; --j)
Toshihiro Shimizu 890ddd
				polyline.push_back(T3DPointD(polyline2d[j], 0.0));
Toshihiro Shimizu 890ddd
			i = l;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Finally, copy the remaining (forward) ones
Toshihiro Shimizu 890ddd
	for (; i < pointNumber; ++i)
Toshihiro Shimizu 890ddd
		polyline.push_back(T3DPointD(polyline2d[i], 0.0));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return doAntialiasing;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
 This function accept a polygon which can have autointersections, 
Toshihiro Shimizu 890ddd
 and creates a number of not-autointersecting polygons. the second function is for recursive calls.
Toshihiro Shimizu 890ddd
 It is used for The GlTessellator
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
} //end namaspace
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void OutlineRegionProp::computeRegionOutline()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int subRegionNumber = getRegion()->getSubregionCount();
Toshihiro Shimizu 890ddd
	TRegionOutline::PointVector app;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_outline.m_exterior.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	computeOutline(getRegion(), app, m_pixelSize);
Toshihiro Shimizu 890ddd
	m_outline.m_doAntialiasing = true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_outline.m_exterior.push_back(app);
Toshihiro Shimizu 890ddd
	m_outline.m_interior.clear();
Toshihiro Shimizu 890ddd
	m_outline.m_interior.reserve(subRegionNumber);
Toshihiro Shimizu 890ddd
	for (int i = 0; i < subRegionNumber; i++) {
Toshihiro Shimizu 890ddd
		app.clear();
Toshihiro Shimizu 890ddd
		computeOutline(getRegion()->getSubregion(i), app, m_pixelSize);
Toshihiro Shimizu 890ddd
		m_outline.m_doAntialiasing = true;
Toshihiro Shimizu 890ddd
		m_outline.m_interior.push_back(app);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_outline.m_bbox = getRegion()->getBBox();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
OutlineRegionProp::OutlineRegionProp(const TRegion *region, const TOutlineStyleP colorStyle)
Toshihiro Shimizu 890ddd
	: TRegionProp(region), m_pixelSize(0), m_colorStyle(colorStyle)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_styleVersionNumber = m_colorStyle->getVersionNumber();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void OutlineRegionProp::draw(const TVectorRenderData &rd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (rd.m_clippingRect != TRect() && !rd.m_is3dView && !(rd.m_aff * getRegion()->getBBox()).overlaps(convert(rd.m_clippingRect)))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glPushMatrix();
Toshihiro Shimizu 890ddd
	tglMultMatrix(rd.m_aff);
Toshihiro Shimizu 890ddd
	double pixelSize = sqrt(tglGetPixelSize2());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!isAlmostZero(pixelSize - m_pixelSize, 1e-5) ||
Toshihiro Shimizu 890ddd
		m_regionChanged ||
Toshihiro Shimizu 890ddd
		m_styleVersionNumber != m_colorStyle->getVersionNumber()) {
Toshihiro Shimizu 890ddd
		m_pixelSize = pixelSize;
Toshihiro Shimizu 890ddd
		m_regionChanged = false;
Toshihiro Shimizu 890ddd
		computeRegionOutline();
Toshihiro Shimizu 890ddd
		TOutlineStyle::RegionOutlineModifier *modifier = m_colorStyle->getRegionOutlineModifier();
Toshihiro Shimizu 890ddd
		if (modifier)
Toshihiro Shimizu 890ddd
			modifier->modify(m_outline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_styleVersionNumber = m_colorStyle->getVersionNumber();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(!m_outline.m_exterior.empty());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_colorStyle->drawRegion(rd.m_cf,
Toshihiro Shimizu 890ddd
							 rd.m_antiAliasing && rd.m_regionAntialias,
Toshihiro Shimizu 890ddd
							 m_outline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glPopMatrix();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRegionProp *OutlineRegionProp::clone(const TRegion *region) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	OutlineRegionProp *prop = new OutlineRegionProp(region, m_colorStyle);
Toshihiro Shimizu 890ddd
	prop->m_regionChanged = m_regionChanged;
Toshihiro Shimizu 890ddd
	prop->m_pixelSize = m_pixelSize;
Toshihiro Shimizu 890ddd
	prop->m_outline = m_outline;
Toshihiro Shimizu 890ddd
	return prop;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TColorStyle *OutlineRegionProp::getColorStyle() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_colorStyle.getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void OutlineRegionProp::draw(TFlash &flash)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_colorStyle->drawRegion(flash, getRegion());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//flash.setColor(m_colorStyle->getMainColor());
Toshihiro Shimizu 890ddd
m_colorStyle->setFill(flash);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//rd.setTexture(m_colorStyle->getMainColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (i=0; i<(int)r->getEdgeCount(); i++)
Toshihiro Shimizu 890ddd
	computeQuadChain(*r->getEdge(i), quadArray, toBeDeleted);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
flash.drawPolygon(quadArray);
Toshihiro Shimizu 890ddd
clearPointerContainer(toBeDeleted);
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}