Esempio n. 1
0
int CalligraphicShader::shade(Stroke &ioStroke) const
{
  Interface0DIterator v;
  Functions0D::VertexOrientation2DF0D fun;
  StrokeVertex *sv;
  for (v = ioStroke.verticesBegin(); !v.isEnd(); ++v) {
    real thickness;
    if (fun(v) < 0)
      return -1;

    Vec2f vertexOri(fun.result);
    Vec2r ori2d(-vertexOri[1], vertexOri[0]);
    ori2d.normalizeSafe();
    real scal = ori2d * _orientation;
    sv = dynamic_cast<StrokeVertex *>(&(*v));
    if (_clamp && (scal < 0)) {
      scal = 0.0;
      sv->attribute().setColor(1, 1, 1);
    }
    else {
      scal = fabs(scal);
      sv->attribute().setColor(0, 0, 0);
    }
    thickness = _minThickness + scal * (_maxThickness - _minThickness);
    if (thickness < 0.0)
      thickness = 0.0;
    sv->attribute().setThickness(thickness / 2.0, thickness / 2.0);
  }

  return 0;
}
Esempio n. 2
0
int SpatialNoiseShader::shade(Stroke &ioStroke) const
{
  Interface0DIterator v, v2;
  v = ioStroke.verticesBegin();
  Vec2r p(v->getProjectedX(), v->getProjectedY());
  v2 = v;
  ++v2;
  Vec2r p0(v2->getProjectedX(), v2->getProjectedY());
  p0 = p + 2 * (p - p0);
  StrokeVertex *sv;
  sv = dynamic_cast<StrokeVertex *>(&(*v));
  real initU = sv->strokeLength() * real(NB_VALUE_NOISE);
  if (_pureRandom)
    initU += RandGen::drand48() * real(NB_VALUE_NOISE);

  Functions0D::VertexOrientation2DF0D fun;
  while (!v.isEnd()) {
    sv = dynamic_cast<StrokeVertex *>(&(*v));
    Vec2r p(sv->getPoint());
    if (fun(v) < 0)
      return -1;
    Vec2r vertexOri(fun.result);
    Vec2r ori2d(vertexOri[0], vertexOri[1]);
    ori2d = Vec2r(p - p0);
    ori2d.normalizeSafe();

    PseudoNoise mynoise;
    real bruit;

    if (_smooth)
      bruit = mynoise.turbulenceSmooth(_xScale * sv->curvilinearAbscissa() + initU, _nbOctave);
    else
      bruit = mynoise.turbulenceLinear(_xScale * sv->curvilinearAbscissa() + initU, _nbOctave);

    Vec2r noise(-ori2d[1] * _amount * bruit, ori2d[0] * _amount * bruit);

    sv->setPoint(p[0] + noise[0], p[1] + noise[1]);
    p0 = p;

    ++v;
  }

  ioStroke.UpdateLength();

  return 0;
}
Esempio n. 3
0
static Stroke *createStroke(Interface1D& inter)
{
	Stroke *stroke = new Stroke;
	stroke->setId(inter.getId());

	float currentCurvilignAbscissa = 0.0f;

	Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd();
	Interface0DIterator itfirst = it;

	Vec2r current(it->getPoint2D());
	Vec2r previous = current;
	SVertex *sv;
	CurvePoint *cp;
	StrokeVertex *stroke_vertex = NULL;
	bool hasSingularity = false;

	do {
		cp = dynamic_cast<CurvePoint*>(&(*it));
		if (!cp) {
			sv = dynamic_cast<SVertex*>(&(*it));
			if (!sv) {
				cerr << "Warning: unexpected Vertex type" << endl;
				continue;
			}
			stroke_vertex = new StrokeVertex(sv);
		}
		else {
			stroke_vertex = new StrokeVertex(cp);
		}
		current = stroke_vertex->getPoint2D();
		Vec2r vec_tmp(current - previous);
		real dist = vec_tmp.norm();
		if (dist < 1.0e-6)
			hasSingularity = true;
		currentCurvilignAbscissa += dist;
		stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa);
		stroke->push_back(stroke_vertex);
		previous = current;
		++it;
	} while ((it != itend) && (it != itfirst));

	if (it == itfirst) {
		// Add last vertex:
		cp = dynamic_cast<CurvePoint*>(&(*it));
		if (!cp) {
			sv = dynamic_cast<SVertex*>(&(*it));
			if (!sv)
				cerr << "Warning: unexpected Vertex type" << endl;
			else
				stroke_vertex = new StrokeVertex(sv);
		}
		else {
			stroke_vertex = new StrokeVertex(cp);
		}
		current = stroke_vertex->getPoint2D();
		Vec2r vec_tmp(current - previous);
		real dist = vec_tmp.norm();
		if (dist < 1.0e-6)
			hasSingularity = true;
		currentCurvilignAbscissa += dist;
		stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa);
		stroke->push_back(stroke_vertex);
	}
	// Discard the stroke if the number of stroke vertices is less than two
	if (stroke->strokeVerticesSize() < 2) {
		delete stroke;
		return NULL;
	}
	stroke->setLength(currentCurvilignAbscissa);
	if (hasSingularity) {
		// Try to address singular points such that the distance between two subsequent vertices
		// are smaller than epsilon.
		StrokeInternal::StrokeVertexIterator v = stroke->strokeVerticesBegin();
		StrokeInternal::StrokeVertexIterator vnext = v;
		++vnext;
		Vec2r next((*v).getPoint());
		while (!vnext.isEnd()) {
			current = next;
			next = (*vnext).getPoint();
			if ((next - current).norm() < 1.0e-6) {
				StrokeInternal::StrokeVertexIterator vprevious = v;
				if (!vprevious.isBegin())
					--vprevious;

				// collect a set of overlapping vertices
				std::vector<StrokeVertex *> overlapping_vertices;
				overlapping_vertices.push_back(&(*v));
				do {
					overlapping_vertices.push_back(&(*vnext));
					current = next;
					++v;
					++vnext;
					if (vnext.isEnd())
						break;
					next = (*vnext).getPoint();
				} while ((next - current).norm() < 1.0e-6);

				Vec2r target;
				bool reverse;
				if (!vnext.isEnd()) {
					target = (*vnext).getPoint();
					reverse = false;
				}
				else if (!vprevious.isBegin()) {
					target = (*vprevious).getPoint();
					reverse = true;
				}
				else {
					// Discard the stroke because all stroke vertices are overlapping
					delete stroke;
					return NULL;
				}
				current = overlapping_vertices.front()->getPoint();
				Vec2r dir(target - current);
				real dist = dir.norm();
				real len = 1.0e-3; // default offset length
				int nvert = overlapping_vertices.size();
				if (dist < len * nvert) {
					len = dist / nvert;
				}
				dir.normalize();
				Vec2r offset(dir * len);
				// add the offset to the overlapping vertices
				StrokeVertex *sv;
				std::vector<StrokeVertex *>::iterator it = overlapping_vertices.begin();
				if (!reverse) {
					for (int n = 0; n < nvert; n++) {
						sv = (*it);
						sv->setPoint(sv->getPoint() + offset * (n + 1));
						++it;
					}
				}
				else {
					for (int n = 0; n < nvert; n++) {
						sv = (*it);
						sv->setPoint(sv->getPoint() + offset * (nvert - n));
						++it;
					}
				}

				if (vnext.isEnd())
					break;
			}
			++v;
			++vnext;
		}
	}
	{
		// Check if the stroke no longer contains singular points
		Interface0DIterator v = stroke->verticesBegin();
		Interface0DIterator vnext = v;
		++vnext;
		Vec2r next((*v).getPoint2D());
		bool warning = false;
		while (!vnext.isEnd()) {
			current = next;
			next = (*vnext).getPoint2D();
			if ((next - current).norm() < 1.0e-6) {
				warning = true;
				break;
			}
			++v;
			++vnext;
		}
		if (warning && G.debug & G_DEBUG_FREESTYLE) {
			printf("Warning: stroke contains singular points.\n");
		}
	}
	return stroke;
}