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); }
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; }
void Stroke::InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next) { vertex_container::iterator itnext = next.getIt(); _Vertices.insert(itnext, iVertex); UpdateLength(); }
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; }