ShapeDistanceFinder.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "ShapeDistanceFinder.h"
  2. namespace msdfgen {
  3. template <class ContourCombiner>
  4. ShapeDistanceFinder<ContourCombiner>::ShapeDistanceFinder(const Shape &shape) : shape(shape), contourCombiner(shape), shapeEdgeCache(shape.edgeCount()) { }
  5. template <class ContourCombiner>
  6. typename ShapeDistanceFinder<ContourCombiner>::DistanceType ShapeDistanceFinder<ContourCombiner>::distance(const Point2 &origin) {
  7. contourCombiner.reset(origin);
  8. #ifdef MSDFGEN_USE_CPP11
  9. typename ContourCombiner::EdgeSelectorType::EdgeCache *edgeCache = shapeEdgeCache.data();
  10. #else
  11. typename ContourCombiner::EdgeSelectorType::EdgeCache *edgeCache = shapeEdgeCache.empty() ? NULL : &shapeEdgeCache[0];
  12. #endif
  13. for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) {
  14. if (!contour->edges.empty()) {
  15. typename ContourCombiner::EdgeSelectorType &edgeSelector = contourCombiner.edgeSelector(int(contour-shape.contours.begin()));
  16. const EdgeSegment *prevEdge = contour->edges.size() >= 2 ? *(contour->edges.end()-2) : *contour->edges.begin();
  17. const EdgeSegment *curEdge = contour->edges.back();
  18. for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
  19. const EdgeSegment *nextEdge = *edge;
  20. edgeSelector.addEdge(*edgeCache++, prevEdge, curEdge, nextEdge);
  21. prevEdge = curEdge;
  22. curEdge = nextEdge;
  23. }
  24. }
  25. }
  26. return contourCombiner.distance();
  27. }
  28. template <class ContourCombiner>
  29. typename ShapeDistanceFinder<ContourCombiner>::DistanceType ShapeDistanceFinder<ContourCombiner>::oneShotDistance(const Shape &shape, const Point2 &origin) {
  30. ContourCombiner contourCombiner(shape);
  31. contourCombiner.reset(origin);
  32. for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) {
  33. if (!contour->edges.empty()) {
  34. typename ContourCombiner::EdgeSelectorType &edgeSelector = contourCombiner.edgeSelector(int(contour-shape.contours.begin()));
  35. const EdgeSegment *prevEdge = contour->edges.size() >= 2 ? *(contour->edges.end()-2) : *contour->edges.begin();
  36. const EdgeSegment *curEdge = contour->edges.back();
  37. for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
  38. const EdgeSegment *nextEdge = *edge;
  39. typename ContourCombiner::EdgeSelectorType::EdgeCache dummy;
  40. edgeSelector.addEdge(dummy, prevEdge, curEdge, nextEdge);
  41. prevEdge = curEdge;
  42. curEdge = nextEdge;
  43. }
  44. }
  45. }
  46. return contourCombiner.distance();
  47. }
  48. }