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; }
float GetViewMapGradientNormF0D::operator()(Interface0DIterator& iter){ SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); float pxy = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); float gx = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX()+_step, (int)iter->getProjectedY()) - pxy; float gy = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()+_step) - pxy; float f = Vec2f(gx,gy).norm(); return f; }
real Curvature2DAngleF0D::operator()(Interface0DIterator& iter) { Interface0DIterator tmp1 = iter, tmp2 = iter; ++tmp2; unsigned count = 1; while((!tmp1.isBegin()) && (count < 3)) { --tmp1; ++count; } while((!tmp2.isEnd()) && (count < 3)) { ++tmp2; ++count; } if(count < 3) return 0; // if we only have 2 vertices Interface0DIterator v = iter; if(iter.isBegin()) ++v; Interface0DIterator next=v; ++next; if(next.isEnd()) { next = v; --v; } Interface0DIterator prev=v; --prev; Vec2r A(prev->getProjectedX(), prev->getProjectedY()); Vec2r B(v->getProjectedX(), v->getProjectedY()); Vec2r C(next->getProjectedX(), next->getProjectedY()); Vec2r AB(B-A); Vec2r BC(C-B); Vec2r N1(-AB[1], AB[0]); if(N1.norm() != 0) N1.normalize(); Vec2r N2(-BC[1], BC[0]); if(N2.norm() != 0) N2.normalize(); if((N1.norm() == 0) && (N2.norm() == 0)) { Exception::raiseException(); return 0; } double cosin = N1*N2; if(cosin > 1) cosin = 1; if(cosin < -1) cosin = -1; return acos(cosin); }
Nature::EdgeNature CurveNatureF1D::operator()(Interface1D& inter) { ViewEdge* ve = dynamic_cast<ViewEdge*>(&inter); if (ve) return ve->getNature(); else{ // we return a nature that contains every // natures of the viewedges spanned by the chain. Nature::EdgeNature nat = Nature::NO_FEATURE; Interface0DIterator it = inter.verticesBegin(); while(!it.isEnd()){ nat |= _func(it); ++it; } return nat; } }
double LocalAverageDepthF0D::operator()(Interface0DIterator& iter) { Canvas * iViewer = Canvas::getInstance(); int bound = _filter.getBound(); if( (iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>iViewer->width()) || (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>iViewer->height())) return 0.0; GrayImage image ; iViewer->readDepthPixels((int)iter->getProjectedX()-bound,(int)iter->getProjectedY()-bound,_filter.maskSize(),_filter.maskSize(),image); return _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); }
unsigned int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) { ViewEdge * ve1, *ve2; getViewEdges(iter,ve1,ve2); unsigned int qi1, qi2; qi1 = ve1->qi(); if(ve2 != 0){ qi2 = ve2->qi(); if(qi2!=qi1) cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl; } return qi1; }
double DensityF0D::operator()(Interface0DIterator& iter) { Canvas* canvas = Canvas::getInstance(); int bound = _filter.getBound(); if( (iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>canvas->width()) || (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>canvas->height())) return 0.0; RGBImage image; canvas->readColorPixels((int)iter->getProjectedX() - bound, (int)iter->getProjectedY() - bound, _filter.maskSize(), _filter.maskSize(), image); return _filter.getSmoothedPixel<RGBImage>(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); }
int QuantitativeInvisibilityF0D::operator()(Interface0DIterator& iter) { ViewEdge *ve1, *ve2; getViewEdges(iter, ve1, ve2); unsigned int qi1, qi2; qi1 = ve1->qi(); if (ve2 != NULL) { qi2 = ve2->qi(); if (qi2 != qi1) { if (G.debug & G_DEBUG_FREESTYLE) { cout << "QuantitativeInvisibilityF0D: ambiguous evaluation for point " << iter->getId() << endl; } } } result = qi1; return 0; }
float ReadCompleteViewMapPixelF0D::operator()(Interface0DIterator& iter) { SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); float v = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); return v; }
float ReadMapPixelF0D::operator()(Interface0DIterator& iter) { Canvas * canvas = Canvas::getInstance(); return canvas->readMapPixel(_mapName, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY()); }
void getFEdges(Interface0DIterator& it, FEdge*& fe1, FEdge*& fe2) { // count number of vertices Interface0DIterator prev = it, next = it; ++next; int count = 1; while((!prev.isBegin()) && (count < 3)) { --prev; ++count; } while((!next.isEnd()) && (count < 3)) { ++next; ++count; } if(count < 3) { // if we only have 2 vertices FEdge * fe = 0; Interface0DIterator tmp = it; if(it.isBegin()) { ++tmp; fe = it->getFEdge(*tmp); } else { --tmp; fe = it->getFEdge(*tmp); } fe1 = fe; fe2 = 0; } else { // we have more than 2 vertices bool begin=false,last=false; Interface0DIterator previous = it; if(!previous.isBegin()) --previous; else begin=true; Interface0DIterator next = it; ++next; if(next.isEnd()) last = true; if(begin) { fe1 = it->getFEdge(*next); fe2 = 0; } else if(last) { fe1 = previous->getFEdge(*it); fe2 = 0; } else { fe1 = previous->getFEdge(*it); fe2 = it->getFEdge(*next); } } }
Vec3f VertexOrientation3DF0D::operator()(Interface0DIterator& iter) { Vec3r A,C; Vec3r B(iter->getX(), iter->getY(), iter->getZ()); if(iter.isBegin()) A = Vec3r(iter->getX(), iter->getY(), iter->getZ()); else { Interface0DIterator previous = iter; --previous ; A = Vec3r(previous->getX(), previous->getY(), previous->getZ()); } Interface0DIterator next = iter; ++next ; if(next.isEnd()) C = Vec3r(iter->getX(), iter->getY(), iter->getZ()); else C = Vec3r(next->getX(), next->getY(), next->getZ()); Vec3r AB(B-A); if(AB.norm() != 0) AB.normalize(); Vec3r BC(C-B); if(BC.norm() != 0) BC.normalize(); Vec3f res (AB + BC); if(res.norm() != 0) res.normalize(); return res; }
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; }
int VertexOrientation2DF0D::operator()(Interface0DIterator& iter) { Vec2f A, C; Vec2f B(iter->getProjectedX(), iter->getProjectedY()); if (iter.isBegin()) { A = Vec2f(iter->getProjectedX(), iter->getProjectedY()); } else { Interface0DIterator previous = iter; --previous ; A = Vec2f(previous->getProjectedX(), previous->getProjectedY()); } Interface0DIterator next = iter; ++next; if (next.isEnd()) C = Vec2f(iter->getProjectedX(), iter->getProjectedY()); else C = Vec2f(next->getProjectedX(), next->getProjectedY()); Vec2f AB(B - A); if (AB.norm() != 0) AB.normalize(); Vec2f BC(C - B); if (BC.norm() != 0) BC.normalize(); result = AB + BC; if (result.norm() != 0) result.normalize(); return 0; }