commit 46e8dfae2032995927a7950a3a94e8e93037e0a0
parent d710029da754b33bb63b40e32c9d913a583827f1
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 26 Aug 2016 15:49:57 +0200
Clip only the triangles that intersect the clip polygon AABB
Diffstat:
| M | src/cpr_mesh.c | | | 67 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
1 file changed, 63 insertions(+), 4 deletions(-)
diff --git a/src/cpr_mesh.c b/src/cpr_mesh.c
@@ -83,6 +83,21 @@ cInt_to_double(const ClipperLib::cInt i, const double scale)
}
static INLINE int
+aabb_intersect
+ (const double lower0[2],
+ const double upper0[2],
+ const double lower1[2],
+ const double upper1[2])
+{
+ ASSERT(lower0 && upper0 && lower1 && upper1);
+ return lower0[0] < upper1[0]
+ && lower0[1] < upper1[1]
+ && lower1[0] < upper0[0]
+ && lower1[1] < upper0[1];
+}
+
+
+static INLINE int
aabb_is_degenerated(const double lower[2], const double upper[2])
{
ASSERT(lower && upper);
@@ -136,6 +151,23 @@ error:
goto exit;
}
+static void
+triangle_compute_aabb
+ (double tri[3][2],
+ double lower[2],
+ double upper[2])
+{
+ size_t ivert;
+ ASSERT(tri && lower && upper);
+
+ d2_splat(lower, DBL_MAX);
+ d2_splat(upper,-DBL_MAX);
+ FOR_EACH(ivert, 0, 3) {
+ d2_min(lower, lower, tri[ivert]);
+ d2_max(upper, upper, tri[ivert]);
+ }
+}
+
static res_T
register_vertex
(const double pos[2],
@@ -179,6 +211,24 @@ error:
goto exit;
}
+static FINLINE res_T
+register_triangle
+ (double tri[3][2],
+ struct darray_double* coords, /* Vertex buffer */
+ struct darray_size_t* indices, /* Index buffer */
+ struct htable_vertex* vertices) /* Map a vertex to its index */
+{
+ size_t ivert;
+ res_T res = RES_OK;
+ ASSERT(tri && coords && indices && vertices);
+ FOR_EACH(ivert, 0, 3) {
+ res = register_vertex(tri[ivert], coords, indices, vertices);
+ if(res != RES_OK) return res;
+ }
+ return RES_OK;
+}
+
+
static res_T
register_paths
(const ClipperLib::Paths& paths,
@@ -478,17 +528,26 @@ cpr_mesh_clip(struct cpr_mesh* mesh, struct cpr_polygon* poly_desc)
CPR(mesh_get_triangles_count(mesh, &ntris));
FOR_EACH(itri, 0, ntris) {
size_t ids[3];
+ double tri[3][2];
CPR(mesh_get_indices(mesh, itri, ids));
+ CPR(mesh_get_position(mesh, ids[0], tri[0]));
+ CPR(mesh_get_position(mesh, ids[1], tri[1]));
+ CPR(mesh_get_position(mesh, ids[2], tri[2]));
+ triangle_compute_aabb(tri, lower, upper);
+
+ if(!aabb_intersect(lower, upper, poly.lower, poly.upper)) {
+ res = register_triangle(tri, &coords, &indices, &vertices);
+ if(res != RES_OK) goto error;
+ continue;
+ }
/* Setup the candidate path */
cand_path.clear();
FOR_EACH(ivert, 0, 3) {
- double pos[2];
ClipperLib::IntPoint pt;
- CPR(mesh_get_position(mesh, ids[ivert], pos));
- pt.X = double_to_cInt(pos[0], extend[0]);
- pt.Y = double_to_cInt(pos[1], extend[1]);
+ pt.X = double_to_cInt(tri[ivert][0], extend[0]);
+ pt.Y = double_to_cInt(tri[ivert][1], extend[1]);
cand_path.push_back(pt);
}