@@ -783,6 +783,7 @@
Loading
783 783
784 784
template <typename N = uint32_t, typename Polygon>
785 785
std::vector<N> earcut(const Polygon& poly) {
786 +
786 787
    mapbox::detail::Earcut<N> earcut;
787 788
    earcut(poly);
788 789
    return std::move(earcut.indices);

@@ -3,57 +3,21 @@
Loading
3 3
using namespace Rcpp;
4 4
#include "earcut.h"
5 5
6 +
#include "decido/decido.hpp"
6 7
7 8
// [[Rcpp::export]]
8 -
IntegerVector earcut_cpp(NumericVector x, NumericVector y,
9 -
                     IntegerVector holes,
10 -
                     IntegerVector numholes) {
11 -
  using Coord = double;
12 -
  // The index type. Defaults to uint32_t, but you can also pass uint16_t if you know that your
13 -
  // data won't have more than 65536 vertices.
14 -
  using N = uint32_t;
15 -
  // Create array
16 -
  using Point = std::array<Coord, 2>;
17 -
  using Polygon = std::vector<Point>;
18 -
  Polygon poly;
19 -
  using Polygons = std::vector<Polygon>;
20 -
21 -
  int vcount = static_cast <int> (x.length());
22 -
  Point pt;
23 -
  Polygons polyrings;
24 -
 // if (numholes.size())
25 -
//    Rcout << "numholes[0]:" << numholes[0] << std::endl;
26 -
  int hole_index = 0;
27 -
  for (int ipoint = 0; ipoint < vcount; ipoint++) {
28 -
    pt = {x[ipoint], y[ipoint]};
29 -
    // don't add the point if we are starting a new ring
30 -
    if (numholes.size() && numholes[0] > 0) {
31 -
      if (hole_index < holes.size()) {
32 -
//         throw std::runtime_error("bounds");
33 -
      int ihole = holes[hole_index];
34 -
      if (ipoint == ihole) {
35 -
        // Rprintf("pushback poly %i\n", ipoint + 1);
36 -
        polyrings.push_back(poly);
37 -
        poly.clear();
38 -
        hole_index++;
39 -
      }
40 -
      }
41 -
    }
42 -
    // now add the point
43 -
    poly.push_back(pt);
44 -
  }
9 +
Rcpp::IntegerVector earcut_cpp(
10 +
    NumericVector x,
11 +
    NumericVector y,
12 +
    IntegerVector holes,
13 +
    IntegerVector numholes
14 +
  ) {
15 +
  return decido::api::earcut( x, y, holes, numholes );
16 +
}
45 17
46 -
  // ensure we catch the last poly ring
47 -
  polyrings.push_back(poly);
48 -
  // Run tessellation
49 -
  // Returns array of indices that refer to the vertices of the input polygon.
50 -
  // Three subsequent indices form a triangle.
51 -
  std::vector<N> indices = mapbox::earcut<N>(polyrings);
52 18
53 -
  IntegerVector out(indices.size());
54 -
  for (size_t j = 0; j < static_cast <size_t> (out.length()); j++){
55 -
    out[static_cast <R_xlen_t> (j)] = static_cast <int> (indices[j]);
56 -
  }
57 -
  return out;
19 +
// [[Rcpp::export]]
20 +
Rcpp::IntegerVector earcut_sfg( SEXP& sfg ) {
21 +
  return decido::api::earcut( sfg );
58 22
}
59 23

@@ -0,0 +1,207 @@
Loading
1 +
#ifndef R_DECIDO_EARCUT_H
2 +
#define R_DECIDO_EARCUT_H
3 +
4 +
#include <RcppCommon.h>
5 +
#include <array>
6 +
#include "earcut.h"
7 +
8 +
9 +
namespace Rcpp {
10 +
11 +
  template < typename T > SEXP wrap( std::array< T, 2 >& Point );
12 +
  template < typename T > SEXP wrap( std::vector< std::array< T, 2 > >& Polygon );
13 +
  template < typename T > SEXP wrap( std::vector< std::vector< std::array< T, 2 > > >& Polygons );
14 +
15 +
namespace traits {
16 +
17 +
  template < typename T > class Exporter< std::array< T, 2 > >;
18 +
  template < typename T > class Exporter< std::vector< std::array< T, 2 > > >;
19 +
  template < typename T > class Exporter< std::vector< std::vector< std::array< T, 2 > > > >;
20 +
21 +
} // traits
22 +
} // Rcpp
23 +
24 +
#include <Rcpp.h>
25 +
26 +
namespace Rcpp {
27 +
28 +
  template <typename T>
29 +
  SEXP wrap( std::array< T, 2 >& Point ) {
30 +
    Rcpp::NumericVector v(2);
31 +
    v[0] = Point[0];
32 +
    v[1] = Point[1];
33 +
    return v;
34 +
  }
35 +
36 +
  template < typename T >
37 +
  SEXP wrap( std::vector< std::array< T, 2 > >& Polygon ) {
38 +
    R_xlen_t n = Polygon.size();
39 +
    Rcpp::NumericMatrix mat( n, 2 );
40 +
    R_xlen_t i;
41 +
    for( i = 0; i < n; ++i ) {
42 +
      std::array< T, 2 > pt =  Polygon[ i ];
43 +
      Rcpp::NumericVector nv = Rcpp::wrap( pt );
44 +
      mat( i, Rcpp::_ ) = nv;
45 +
    }
46 +
    return mat;
47 +
  }
48 +
49 +
  template < typename T >
50 +
  SEXP wrap( std::vector< std::vector< std::array< T, 2 > > >& Polygons ) {
51 +
    R_xlen_t n = Polygons.size();
52 +
    Rcpp::List lst( n );
53 +
    R_xlen_t i;
54 +
    for( i = 0; i < n; ++i ) {
55 +
      std::vector< std::array< T, 2 > > polygon = Polygons[ i ];
56 +
      lst[ i ] = Rcpp::wrap( polygon );
57 +
    }
58 +
    return lst;
59 +
  }
60 +
61 +
namespace traits {
62 +
63 +
  template < typename T > class Exporter< std::array< T, 2 > > {
64 +
    typedef typename std::array< T, 2 > Point;
65 +
66 +
    const static int RTYPE = Rcpp::traits::r_sexptype_traits< T >::rtype;
67 +
    Rcpp::Vector< RTYPE > vec;
68 +
69 +
  public:
70 +
    Exporter( SEXP x ) : vec( x ) {
71 +
      if( TYPEOF( x ) != RTYPE ) {
72 +
        throw std::invalid_argument("decido - invalid R object for creating a Point");
73 +
      }
74 +
    }
75 +
76 +
    Point get() {
77 +
      if( vec.length() != 2 ) {
78 +
        Rcpp::stop("decido - each point in the polygon must have exactly two coordinates");
79 +
      }
80 +
      Point x({ vec[0], vec[1] });
81 +
      return x;
82 +
    }
83 +
84 +
  };
85 +
86 +
  template < typename T > class Exporter< std::vector< std::array< T, 2 > > > {
87 +
    typedef typename std::vector< std::array< T, 2 > > Polygon;
88 +
89 +
    const static int RTYPE = Rcpp::traits::r_sexptype_traits< T >::rtype;
90 +
    Rcpp::Matrix< RTYPE > mat;
91 +
92 +
  public:
93 +
    Exporter( SEXP x ) : mat( x ) {
94 +
      if( TYPEOF( x ) != RTYPE ) {
95 +
        throw std::invalid_argument("decido - invalid R object for creating a Polygon");
96 +
      }
97 +
    }
98 +
99 +
    Polygon get() {
100 +
      R_xlen_t n_row = mat.nrow();
101 +
      Polygon x( n_row );
102 +
      R_xlen_t i;
103 +
      for( i = 0; i < n_row; ++i ) {
104 +
        Rcpp::Vector< RTYPE > v = mat( i, Rcpp::_);
105 +
        x[i] = Rcpp::as< std::array< T, 2 > >( v );
106 +
      }
107 +
      return x;
108 +
    }
109 +
  };
110 +
111 +
  template< typename T > class Exporter< std::vector< std::vector< std::array< T, 2 > > > > {
112 +
    typedef typename std::vector< std::vector< std::array< T, 2 > > > Polygons;
113 +
114 +
    const static int RTYPE = Rcpp::traits::r_sexptype_traits< T >::rtype;
115 +
    Rcpp::List lst;
116 +
117 +
  public:
118 +
    Exporter( SEXP x ) : lst( x ) { }
119 +
    Polygons get() {
120 +
      R_xlen_t n = lst.size();
121 +
      Polygons x( n );
122 +
      R_xlen_t i;
123 +
      for( i = 0; i < n; ++i ) {
124 +
        if( !Rf_isMatrix( lst[ i ] ) ) {
125 +
          Rcpp::stop("decido - a list must only contain matrices");
126 +
        }
127 +
        Rcpp::Matrix< RTYPE > mat = lst[ i ];
128 +
        x[i] = Rcpp::as< std::vector< std::array< T, 2 > > >( mat );
129 +
      }
130 +
      return x;
131 +
    }
132 +
  };
133 +
134 +
} // traits
135 +
} // Rcpp
136 +
137 +
typedef double Coord;
138 +
typedef std::array< Coord, 2 > Point;
139 +
typedef std::vector< Point > Polygon;
140 +
typedef std::vector< Polygon > Polygons;
141 +
142 +
namespace decido {
143 +
namespace api {
144 +
145 +
  inline Rcpp::IntegerVector earcut(
146 +
    Rcpp::NumericVector& x,
147 +
    Rcpp::NumericVector& y,
148 +
    IntegerVector& holes,
149 +
    IntegerVector& numholes
150 +
  ) {
151 +
    // The index type. Defaults to uint32_t, but you can also pass uint16_t if you know that your
152 +
    // data won't have more than 65536 vertices.
153 +
    using N = uint32_t;
154 +
    Polygon poly;
155 +
156 +
    int vcount = static_cast <int> (x.length());
157 +
    Point pt;
158 +
    Polygons polyrings;
159 +
    // if (numholes.size())
160 +
    //    Rcout << "numholes[0]:" << numholes[0] << std::endl;
161 +
    int hole_index = 0;
162 +
    for (int ipoint = 0; ipoint < vcount; ipoint++) {
163 +
      pt = {x[ipoint], y[ipoint]};
164 +
165 +
      // don't add the point if we are starting a new ring
166 +
      if (numholes.size() && numholes[0] > 0) {
167 +
        if (hole_index < holes.size()) {
168 +
          //         throw std::runtime_error("bounds");
169 +
          int ihole = holes[hole_index];
170 +
          if (ipoint == ihole) {
171 +
            // Rprintf("pushback poly %i\n", ipoint + 1);
172 +
            polyrings.push_back(poly);
173 +
            poly.clear();
174 +
            hole_index++;
175 +
          }
176 +
        }
177 +
      }
178 +
      // now add the point
179 +
      poly.push_back(pt);
180 +
    }
181 +
182 +
    // ensure we catch the last poly ring
183 +
    polyrings.push_back(poly);
184 +
185 +
    // Run tessellation
186 +
    // Returns array of indices that refer to the vertices of the input polygon.
187 +
    // Three subsequent indices form a triangle.
188 +
    std::vector<N> indices = mapbox::earcut<N>(polyrings);
189 +
    return Rcpp::wrap( indices );
190 +
  }
191 +
192 +
  inline Rcpp::IntegerVector earcut(
193 +
      SEXP& polygon
194 +
  ) {
195 +
    if( TYPEOF( polygon ) != VECSXP ) {
196 +
      Rcpp::stop("decido - expecting a list of matrices");
197 +
    }
198 +
    Polygons polyrings = Rcpp::as< Polygons >( polygon );
199 +
    std::vector< uint32_t > indices = mapbox::earcut< uint32_t >( polyrings );
200 +
    return Rcpp::wrap( indices );
201 +
  }
202 +
203 +
} // earcut
204 +
} // decido
205 +
206 +
207 +
#endif
0 208
imilarity index 99%
1 209
ename from src/earcut.h
2 210
ename to inst/include/earcut.h
Files Coverage
inst/include 81.63%
R/earcut.R 100.00%
src/decido.cpp 100.00%
Project Totals (4 files) 83.02%
1
comment: false
2

3
coverage:
4
  status:
5
    project:
6
      default:
7
        target: auto
8
        threshold: 1%
9
    patch:
10
      default:
11
        target: auto
12
        threshold: 1%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading