static PyObject *StrokeVertexIterator_incremented(BPy_StrokeVertexIterator *self)
{
	if (self->sv_it->isEnd()) {
		PyErr_SetString(PyExc_RuntimeError, "cannot increment any more");
		return NULL;
	}
	StrokeInternal::StrokeVertexIterator *copy = new StrokeInternal::StrokeVertexIterator(*self->sv_it);
	copy->increment();
	return BPy_StrokeVertexIterator_from_StrokeVertexIterator(*copy, self->reversed);
}
Beispiel #2
0
void TextStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const{
  Stroke *stroke = iStrokeRep->getStroke();
  if(!stroke){
    cerr << "no stroke associated with Rep" << endl;
    return;
  }
    
  StrokeInternal::StrokeVertexIterator v = stroke->strokeVerticesBegin();
  StrokeAttribute att;
  while(!v.isEnd()){
    att = v->attribute();
    _ofstream << v->u() << " " << (double) v->getProjectedX() << " " << (double) v->getProjectedY() << " " << (double) v->getProjectedZ() << " " \
      << att.getThicknessL() << " " << att.getThicknessR() << " " \
      << att.getColorR() << " " << att.getColorG() << " " << att.getColorB() << " ";
    ++v;
  }
  _ofstream << endl;
}
Beispiel #3
0
void Stroke::InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next)
{
  vertex_container::iterator itnext = next.getIt();
  _Vertices.insert(itnext, iVertex);
  UpdateLength();
}
Beispiel #4
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;
}