star-cpr

Clip 2D meshes with 2D polygons
git clone git://git.meso-star.fr/star-cpr.git
Log | Files | Refs | README | LICENSE

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:
Msrc/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); }