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