Revision: 76250
http://sourceforge.net/p/brlcad/code/76250
Author: starseeker
Date: 2020-07-01 17:59:11 +0000 (Wed, 01 Jul 2020)
Log Message:
-----------
Move polygon overlap check
Modified Paths:
--------------
brlcad/trunk/include/dm/bview_util.h
brlcad/trunk/src/libdm/bview_polygon.cpp
brlcad/trunk/src/libged/polyclip.cpp
Modified: brlcad/trunk/include/dm/bview_util.h
===================================================================
--- brlcad/trunk/include/dm/bview_util.h 2020-07-01 17:22:35 UTC (rev
76249)
+++ brlcad/trunk/include/dm/bview_util.h 2020-07-01 17:59:11 UTC (rev
76250)
@@ -27,6 +27,7 @@
#define DM_BVIEW_UTIL_H
#include "common.h"
+#include "bn/tol.h"
#include "dm/defines.h"
#include "dm/bview.h"
@@ -40,6 +41,7 @@
DM_EXPORT fastf_t find_polygon_area(bview_polygon *gpoly, fastf_t sf, matp_t
model2view, fastf_t size);
+DM_EXPORT int polygons_overlap(bview_polygon *polyA, bview_polygon *polyB,
matp_t model2view, struct bn_tol *tol, fastf_t iscale);
__END_DECLS
Modified: brlcad/trunk/src/libdm/bview_polygon.cpp
===================================================================
--- brlcad/trunk/src/libdm/bview_polygon.cpp 2020-07-01 17:22:35 UTC (rev
76249)
+++ brlcad/trunk/src/libdm/bview_polygon.cpp 2020-07-01 17:59:11 UTC (rev
76250)
@@ -31,7 +31,9 @@
#include "clipper.hpp"
#include "vmath.h"
+#include "bu/malloc.h"
#include "bn/mat.h"
+#include "bn/plane.h"
#include "dm/defines.h"
#include "dm/bview_util.h"
@@ -67,6 +69,375 @@
}
+typedef struct {
+ size_t pc_num_points;
+ point2d_t *pc_point;
+} poly_contour_2d;
+
+typedef struct {
+ size_t p_num_contours;
+ int *p_hole;
+ poly_contour_2d *p_contour;
+} polygon_2d;
+
+int
+polygons_overlap(bview_polygon *polyA, bview_polygon *polyB, matp_t
model2view, struct bn_tol *tol, fastf_t iscale)
+{
+ size_t i, j;
+ size_t beginA, endA, beginB, endB;
+ fastf_t tol_dist;
+ fastf_t tol_dist_sq;
+ fastf_t scale;
+ polygon_2d polyA_2d;
+ polygon_2d polyB_2d;
+ point2d_t pt_2d;
+ point_t A;
+ size_t winding = 0;
+ int ret = 0;
+
+ if (polyA->gp_num_contours < 1 || polyA->gp_contour[0].gpc_num_points < 1
||
+ polyB->gp_num_contours < 1 || polyB->gp_contour[0].gpc_num_points < 1)
+ return 0;
+
+ tol_dist = (tol->dist > 0.0) ? tol->dist : BN_TOL_DIST;
+ tol_dist_sq = (tol->dist_sq > 0.0) ? tol->dist_sq : tol_dist * tol_dist;
+ scale = (iscale > (fastf_t)UINT16_MAX) ? iscale : (fastf_t)UINT16_MAX;
+
+ /* Project polyA and polyB onto the view plane */
+ polyA_2d.p_num_contours = polyA->gp_num_contours;
+ polyA_2d.p_hole = (int *)bu_calloc(polyA->gp_num_contours, sizeof(int),
"p_hole");
+ polyA_2d.p_contour = (poly_contour_2d *)bu_calloc(polyA->gp_num_contours,
sizeof(poly_contour_2d), "p_contour");
+
+ for (i = 0; i < polyA->gp_num_contours; ++i) {
+ polyA_2d.p_hole[i] = polyA->gp_hole[i];
+ polyA_2d.p_contour[i].pc_num_points =
polyA->gp_contour[i].gpc_num_points;
+ polyA_2d.p_contour[i].pc_point = (point2d_t
*)bu_calloc(polyA->gp_contour[i].gpc_num_points, sizeof(point2d_t), "pc_point");
+
+ for (j = 0; j < polyA->gp_contour[i].gpc_num_points; ++j) {
+ point_t vpoint;
+
+ MAT4X3PNT(vpoint, model2view, polyA->gp_contour[i].gpc_point[j]);
+ VSCALE(vpoint, vpoint, scale);
+ V2MOVE(polyA_2d.p_contour[i].pc_point[j], vpoint);
+ }
+ }
+
+ polyB_2d.p_num_contours = polyB->gp_num_contours;
+ polyB_2d.p_hole = (int *)bu_calloc(polyB->gp_num_contours, sizeof(int),
"p_hole");
+ polyB_2d.p_contour = (poly_contour_2d *)bu_calloc(polyB->gp_num_contours,
sizeof(poly_contour_2d), "p_contour");
+
+ for (i = 0; i < polyB->gp_num_contours; ++i) {
+ polyB_2d.p_hole[i] = polyB->gp_hole[i];
+ polyB_2d.p_contour[i].pc_num_points =
polyB->gp_contour[i].gpc_num_points;
+ polyB_2d.p_contour[i].pc_point = (point2d_t
*)bu_calloc(polyB->gp_contour[i].gpc_num_points, sizeof(point2d_t), "pc_point");
+
+ for (j = 0; j < polyB->gp_contour[i].gpc_num_points; ++j) {
+ point_t vpoint;
+
+ MAT4X3PNT(vpoint, model2view, polyB->gp_contour[i].gpc_point[j]);
+ VSCALE(vpoint, vpoint, scale);
+ V2MOVE(polyB_2d.p_contour[i].pc_point[j], vpoint);
+ }
+ }
+
+ /*
+ * Check every line segment of polyA against every line segment of polyB.
+ * If there are any intersecting line segments, there exists an overlap.
+ */
+ for (i = 0; i < polyA_2d.p_num_contours; ++i) {
+ for (beginA = 0; beginA < polyA_2d.p_contour[i].pc_num_points;
++beginA) {
+ vect2d_t dirA;
+
+ if (beginA == polyA_2d.p_contour[i].pc_num_points-1)
+ endA = 0;
+ else
+ endA = beginA + 1;
+
+ V2SUB2(dirA, polyA_2d.p_contour[i].pc_point[endA],
polyA_2d.p_contour[i].pc_point[beginA]);
+
+ for (j = 0; j < polyB_2d.p_num_contours; ++j) {
+ for (beginB = 0; beginB < polyB_2d.p_contour[j].pc_num_points;
++beginB) {
+ vect2d_t distvec;
+ vect2d_t dirB;
+
+ if (beginB == polyB_2d.p_contour[j].pc_num_points-1)
+ endB = 0;
+ else
+ endB = beginB + 1;
+
+ V2SUB2(dirB, polyB_2d.p_contour[j].pc_point[endB],
polyB_2d.p_contour[j].pc_point[beginB]);
+
+ if (bn_isect_lseg2_lseg2(distvec,
+
polyA_2d.p_contour[i].pc_point[beginA], dirA,
+
polyB_2d.p_contour[j].pc_point[beginB], dirB,
+ tol) == 1) {
+ /* Check to see if intersection is near an end point */
+ if (!NEAR_EQUAL(distvec[0], 0.0, tol_dist_sq) &&
+ !NEAR_EQUAL(distvec[0], 1.0, tol_dist_sq) &&
+ !NEAR_EQUAL(distvec[1], 0.0, tol_dist_sq) &&
+ !NEAR_EQUAL(distvec[1], 1.0, tol_dist_sq)) {
+ ret = 1;
+ goto end;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < polyB_2d.p_num_contours; ++i) {
+ size_t npts_on_contour = 0;
+ size_t npts_outside = 0;
+
+ /* Skip holes */
+ if (polyB_2d.p_hole[i])
+ continue;
+
+ /* Check if all points in the current polygon B contour are inside A */
+ for (beginB = 0; beginB < polyB_2d.p_contour[i].pc_num_points;
++beginB) {
+ winding = 0;
+ V2MOVE(pt_2d, polyB_2d.p_contour[i].pc_point[beginB]);
+ V2MOVE(A, pt_2d);
+ A[2] = 0.0;
+
+ for (j = 0; j < polyA_2d.p_num_contours; ++j) {
+ point_t B, C;
+ vect_t BmA, CmA;
+ vect_t vcross;
+
+ for (beginA = 0; beginA < polyA_2d.p_contour[j].pc_num_points;
++beginA) {
+ fastf_t dot;
+
+ if (beginA == polyA_2d.p_contour[j].pc_num_points-1)
+ endA = 0;
+ else
+ endA = beginA + 1;
+
+ if (V2NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA],
pt_2d, tol_dist_sq) ||
+ V2NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[endA],
pt_2d, tol_dist_sq)) {
+ /* pt_2d is the same as one of the end points, so count
it */
+ ++npts_on_contour;
+
+ if (polyA_2d.p_hole[j])
+ winding = 0;
+ else
+ winding = 1;
+
+ goto endA;
+ }
+
+ if ((polyA_2d.p_contour[j].pc_point[beginA][1] <= pt_2d[1]
&&
+ polyA_2d.p_contour[j].pc_point[endA][1] > pt_2d[1])) {
+ V2MOVE(B, polyA_2d.p_contour[j].pc_point[endA]);
+ B[2] = 0.0;
+ V2MOVE(C, polyA_2d.p_contour[j].pc_point[beginA]);
+ C[2] = 0.0;
+ } else if ((polyA_2d.p_contour[j].pc_point[endA][1] <=
pt_2d[1] &&
+ polyA_2d.p_contour[j].pc_point[beginA][1] >
pt_2d[1])) {
+ V2MOVE(B, polyA_2d.p_contour[j].pc_point[beginA]);
+ B[2] = 0.0;
+ V2MOVE(C, polyA_2d.p_contour[j].pc_point[endA]);
+ C[2] = 0.0;
+ } else {
+ /* check if the point is on a horizontal edge */
+ if
(NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA][1],
+ polyA_2d.p_contour[j].pc_point[endA][1],
tol_dist_sq) &&
+
NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA][1], pt_2d[1], tol_dist_sq) &&
+ ((polyA_2d.p_contour[j].pc_point[beginA][0] <=
pt_2d[0] &&
+ polyA_2d.p_contour[j].pc_point[endA][0] >=
pt_2d[0]) ||
+ (polyA_2d.p_contour[j].pc_point[endA][0] <=
pt_2d[0] &&
+ polyA_2d.p_contour[j].pc_point[beginA][0] >=
pt_2d[0]))) {
+ ++npts_on_contour;
+
+ if (polyA_2d.p_hole[j])
+ winding = 0;
+ else
+ winding = 1;
+
+ goto endA;
+ }
+
+ continue;
+ }
+
+ VSUB2(BmA, B, A);
+ VSUB2(CmA, C, A);
+ VUNITIZE(BmA);
+ VUNITIZE(CmA);
+ dot = VDOT(BmA, CmA);
+
+ if (NEAR_EQUAL(dot, -1.0, tol_dist_sq) || NEAR_EQUAL(dot,
1.0, tol_dist_sq)) {
+ ++npts_on_contour;
+
+ if (polyA_2d.p_hole[j])
+ winding = 0;
+ else
+ winding = 0;
+
+ goto endA;
+ }
+
+ VCROSS(vcross, BmA, CmA);
+
+ if (vcross[2] > 0)
+ ++winding;
+ }
+ }
+
+ endA:
+ /* found a point on a polygon B contour that's outside of polygon A
*/
+ if (!(winding%2)) {
+ ++npts_outside;
+ if (npts_outside != npts_on_contour) {
+ break;
+ }
+ }
+ }
+
+ /* found a B polygon contour that's completely inside polygon A */
+ if (winding%2 || (npts_outside != 0 &&
+ npts_outside != polyB_2d.p_contour[i].pc_num_points &&
+ npts_outside == npts_on_contour)) {
+ ret = 1;
+ goto end;
+ }
+ }
+
+ for (i = 0; i < polyA_2d.p_num_contours; ++i) {
+ size_t npts_on_contour = 0;
+ size_t npts_outside = 0;
+
+ /* Skip holes */
+ if (polyA_2d.p_hole[i])
+ continue;
+
+ /* Check if all points in the current polygon A contour are inside B */
+ for (beginA = 0; beginA < polyA_2d.p_contour[i].pc_num_points;
++beginA) {
+ winding = 0;
+ V2MOVE(pt_2d, polyA_2d.p_contour[i].pc_point[beginA]);
+ V2MOVE(A, pt_2d);
+ A[2] = 0.0;
+
+ for (j = 0; j < polyB_2d.p_num_contours; ++j) {
+ point_t B, C;
+ vect_t BmA, CmA;
+ vect_t vcross;
+
+ for (beginB = 0; beginB < polyB_2d.p_contour[j].pc_num_points;
++beginB) {
+ fastf_t dot;
+
+ if (beginB == polyB_2d.p_contour[j].pc_num_points-1)
+ endB = 0;
+ else
+ endB = beginB + 1;
+
+ if (V2NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB],
pt_2d, tol_dist_sq) ||
+ V2NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[endB],
pt_2d, tol_dist_sq)) {
+ /* pt_2d is the same as one of the end points, so count
it */
+
+ if (polyB_2d.p_hole[j])
+ winding = 0;
+ else
+ winding = 1;
+
+ ++npts_on_contour;
+ goto endB;
+ }
+
+ if ((polyB_2d.p_contour[j].pc_point[beginB][1] <= pt_2d[1]
&&
+ polyB_2d.p_contour[j].pc_point[endB][1] > pt_2d[1])) {
+ V2MOVE(B, polyB_2d.p_contour[j].pc_point[endB]);
+ B[2] = 0.0;
+ V2MOVE(C, polyB_2d.p_contour[j].pc_point[beginB]);
+ C[2] = 0.0;
+ } else if ((polyB_2d.p_contour[j].pc_point[endB][1] <=
pt_2d[1] &&
+ polyB_2d.p_contour[j].pc_point[beginB][1] >
pt_2d[1])) {
+ V2MOVE(B, polyB_2d.p_contour[j].pc_point[beginB]);
+ B[2] = 0.0;
+ V2MOVE(C, polyB_2d.p_contour[j].pc_point[endB]);
+ C[2] = 0.0;
+ } else {
+ /* check if the point is on a horizontal edge */
+ if
(NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB][1],
+ polyB_2d.p_contour[j].pc_point[endB][1],
tol_dist_sq) &&
+
NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB][1], pt_2d[1], tol_dist_sq) &&
+ ((polyB_2d.p_contour[j].pc_point[beginB][0] <=
pt_2d[0] &&
+ polyB_2d.p_contour[j].pc_point[endB][0] >=
pt_2d[0]) ||
+ (polyB_2d.p_contour[j].pc_point[endB][0] <=
pt_2d[0] &&
+ polyB_2d.p_contour[j].pc_point[beginB][0] >=
pt_2d[0]))) {
+ if (polyB_2d.p_hole[j])
+ winding = 0;
+ else
+ winding = 1;
+
+ ++npts_on_contour;
+
+ goto endB;
+ }
+
+ continue;
+ }
+
+ VSUB2(BmA, B, A);
+ VSUB2(CmA, C, A);
+ VUNITIZE(BmA);
+ VUNITIZE(CmA);
+ dot = VDOT(BmA, CmA);
+
+ if (NEAR_EQUAL(dot, -1.0, tol_dist_sq) || NEAR_EQUAL(dot,
1.0, tol_dist_sq)) {
+ if (polyB_2d.p_hole[j])
+ winding = 0;
+ else
+ winding = 1;
+
+ ++npts_on_contour;
+ goto endB;
+ }
+
+ VCROSS(vcross, BmA, CmA);
+
+ if (vcross[2] > 0)
+ ++winding;
+ }
+ }
+
+ endB:
+ /* found a point on a polygon A contour that's outside of polygon B
*/
+ if (!(winding%2)) {
+ ++npts_outside;
+ if (npts_outside != npts_on_contour) {
+ break;
+ }
+ }
+ }
+
+ /* found an A polygon contour that's completely inside polygon B */
+ if (winding%2 || (npts_outside != 0 &&
+ npts_outside != polyA_2d.p_contour[i].pc_num_points &&
+ npts_outside == npts_on_contour)) {
+ ret = 1;
+ break;
+ } else
+ ret = 0;
+ }
+
+end:
+
+ for (i = 0; i < polyA->gp_num_contours; ++i)
+ bu_free((void *)polyA_2d.p_contour[i].pc_point, "pc_point");
+ for (i = 0; i < polyB->gp_num_contours; ++i)
+ bu_free((void *)polyB_2d.p_contour[i].pc_point, "pc_point");
+
+ bu_free((void *)polyA_2d.p_hole, "p_hole");
+ bu_free((void *)polyA_2d.p_contour, "p_contour");
+ bu_free((void *)polyB_2d.p_hole, "p_hole");
+ bu_free((void *)polyB_2d.p_contour, "p_contour");
+
+ return ret;
+}
+
+
+
/*
* Local Variables:
* tab-width: 8
Modified: brlcad/trunk/src/libged/polyclip.cpp
===================================================================
--- brlcad/trunk/src/libged/polyclip.cpp 2020-07-01 17:22:35 UTC (rev
76249)
+++ brlcad/trunk/src/libged/polyclip.cpp 2020-07-01 17:59:11 UTC (rev
76250)
@@ -489,374 +489,12 @@
int
ged_polygons_overlap(struct ged *gedp, bview_polygon *polyA, bview_polygon
*polyB)
{
- size_t i, j;
- size_t beginA, endA, beginB, endB;
- fastf_t tol_dist;
- fastf_t tol_dist_sq;
- fastf_t scale;
- polygon_2d polyA_2d;
- polygon_2d polyB_2d;
- point2d_t pt_2d;
- point_t A;
- size_t winding = 0;
- int ret = 0;
-
GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
GED_CHECK_VIEW(gedp, GED_ERROR);
- if (polyA->gp_num_contours < 1 || polyA->gp_contour[0].gpc_num_points < 1
||
- polyB->gp_num_contours < 1 || polyB->gp_contour[0].gpc_num_points < 1)
- return 0;
-
- if (gedp->ged_wdbp->wdb_tol.dist > 0.0)
- tol_dist = gedp->ged_wdbp->wdb_tol.dist;
- else
- tol_dist = BN_TOL_DIST;
-
- if (gedp->ged_wdbp->wdb_tol.dist_sq > 0.0)
- tol_dist_sq = gedp->ged_wdbp->wdb_tol.dist_sq;
- else
- tol_dist_sq = tol_dist * tol_dist;
-
- if (gedp->ged_gvp->gv_scale > (fastf_t)UINT16_MAX)
- scale = gedp->ged_gvp->gv_scale;
- else
- scale = (fastf_t)UINT16_MAX;
-
- /* Project polyA and polyB onto the view plane */
- polyA_2d.p_num_contours = polyA->gp_num_contours;
- polyA_2d.p_hole = (int *)bu_calloc(polyA->gp_num_contours, sizeof(int),
"p_hole");
- polyA_2d.p_contour = (poly_contour_2d *)bu_calloc(polyA->gp_num_contours,
sizeof(poly_contour_2d), "p_contour");
-
- for (i = 0; i < polyA->gp_num_contours; ++i) {
- polyA_2d.p_hole[i] = polyA->gp_hole[i];
- polyA_2d.p_contour[i].pc_num_points =
polyA->gp_contour[i].gpc_num_points;
- polyA_2d.p_contour[i].pc_point = (point2d_t
*)bu_calloc(polyA->gp_contour[i].gpc_num_points, sizeof(point2d_t), "pc_point");
-
- for (j = 0; j < polyA->gp_contour[i].gpc_num_points; ++j) {
- point_t vpoint;
-
- MAT4X3PNT(vpoint, gedp->ged_gvp->gv_model2view,
polyA->gp_contour[i].gpc_point[j]);
- VSCALE(vpoint, vpoint, scale);
- V2MOVE(polyA_2d.p_contour[i].pc_point[j], vpoint);
- }
- }
-
- polyB_2d.p_num_contours = polyB->gp_num_contours;
- polyB_2d.p_hole = (int *)bu_calloc(polyB->gp_num_contours, sizeof(int),
"p_hole");
- polyB_2d.p_contour = (poly_contour_2d *)bu_calloc(polyB->gp_num_contours,
sizeof(poly_contour_2d), "p_contour");
-
- for (i = 0; i < polyB->gp_num_contours; ++i) {
- polyB_2d.p_hole[i] = polyB->gp_hole[i];
- polyB_2d.p_contour[i].pc_num_points =
polyB->gp_contour[i].gpc_num_points;
- polyB_2d.p_contour[i].pc_point = (point2d_t
*)bu_calloc(polyB->gp_contour[i].gpc_num_points, sizeof(point2d_t), "pc_point");
-
- for (j = 0; j < polyB->gp_contour[i].gpc_num_points; ++j) {
- point_t vpoint;
-
- MAT4X3PNT(vpoint, gedp->ged_gvp->gv_model2view,
polyB->gp_contour[i].gpc_point[j]);
- VSCALE(vpoint, vpoint, scale);
- V2MOVE(polyB_2d.p_contour[i].pc_point[j], vpoint);
- }
- }
-
- /*
- * Check every line segment of polyA against every line segment of polyB.
- * If there are any intersecting line segments, there exists an overlap.
- */
- for (i = 0; i < polyA_2d.p_num_contours; ++i) {
- for (beginA = 0; beginA < polyA_2d.p_contour[i].pc_num_points;
++beginA) {
- vect2d_t dirA;
-
- if (beginA == polyA_2d.p_contour[i].pc_num_points-1)
- endA = 0;
- else
- endA = beginA + 1;
-
- V2SUB2(dirA, polyA_2d.p_contour[i].pc_point[endA],
polyA_2d.p_contour[i].pc_point[beginA]);
-
- for (j = 0; j < polyB_2d.p_num_contours; ++j) {
- for (beginB = 0; beginB < polyB_2d.p_contour[j].pc_num_points;
++beginB) {
- vect2d_t distvec;
- vect2d_t dirB;
-
- if (beginB == polyB_2d.p_contour[j].pc_num_points-1)
- endB = 0;
- else
- endB = beginB + 1;
-
- V2SUB2(dirB, polyB_2d.p_contour[j].pc_point[endB],
polyB_2d.p_contour[j].pc_point[beginB]);
-
- if (bn_isect_lseg2_lseg2(distvec,
-
polyA_2d.p_contour[i].pc_point[beginA], dirA,
-
polyB_2d.p_contour[j].pc_point[beginB], dirB,
- &gedp->ged_wdbp->wdb_tol) == 1) {
- /* Check to see if intersection is near an end point */
- if (!NEAR_EQUAL(distvec[0], 0.0, tol_dist_sq) &&
- !NEAR_EQUAL(distvec[0], 1.0, tol_dist_sq) &&
- !NEAR_EQUAL(distvec[1], 0.0, tol_dist_sq) &&
- !NEAR_EQUAL(distvec[1], 1.0, tol_dist_sq)) {
- ret = 1;
- goto end;
- }
- }
- }
- }
- }
- }
-
- for (i = 0; i < polyB_2d.p_num_contours; ++i) {
- size_t npts_on_contour = 0;
- size_t npts_outside = 0;
-
- /* Skip holes */
- if (polyB_2d.p_hole[i])
- continue;
-
- /* Check if all points in the current polygon B contour are inside A */
- for (beginB = 0; beginB < polyB_2d.p_contour[i].pc_num_points;
++beginB) {
- winding = 0;
- V2MOVE(pt_2d, polyB_2d.p_contour[i].pc_point[beginB]);
- V2MOVE(A, pt_2d);
- A[2] = 0.0;
-
- for (j = 0; j < polyA_2d.p_num_contours; ++j) {
- point_t B, C;
- vect_t BmA, CmA;
- vect_t vcross;
-
- for (beginA = 0; beginA < polyA_2d.p_contour[j].pc_num_points;
++beginA) {
- fastf_t dot;
-
- if (beginA == polyA_2d.p_contour[j].pc_num_points-1)
- endA = 0;
- else
- endA = beginA + 1;
-
- if (V2NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA],
pt_2d, tol_dist_sq) ||
- V2NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[endA],
pt_2d, tol_dist_sq)) {
- /* pt_2d is the same as one of the end points, so count
it */
- ++npts_on_contour;
-
- if (polyA_2d.p_hole[j])
- winding = 0;
- else
- winding = 1;
-
- goto endA;
- }
-
- if ((polyA_2d.p_contour[j].pc_point[beginA][1] <= pt_2d[1]
&&
- polyA_2d.p_contour[j].pc_point[endA][1] > pt_2d[1])) {
- V2MOVE(B, polyA_2d.p_contour[j].pc_point[endA]);
- B[2] = 0.0;
- V2MOVE(C, polyA_2d.p_contour[j].pc_point[beginA]);
- C[2] = 0.0;
- } else if ((polyA_2d.p_contour[j].pc_point[endA][1] <=
pt_2d[1] &&
- polyA_2d.p_contour[j].pc_point[beginA][1] >
pt_2d[1])) {
- V2MOVE(B, polyA_2d.p_contour[j].pc_point[beginA]);
- B[2] = 0.0;
- V2MOVE(C, polyA_2d.p_contour[j].pc_point[endA]);
- C[2] = 0.0;
- } else {
- /* check if the point is on a horizontal edge */
- if
(NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA][1],
- polyA_2d.p_contour[j].pc_point[endA][1],
tol_dist_sq) &&
-
NEAR_EQUAL(polyA_2d.p_contour[j].pc_point[beginA][1], pt_2d[1], tol_dist_sq) &&
- ((polyA_2d.p_contour[j].pc_point[beginA][0] <=
pt_2d[0] &&
- polyA_2d.p_contour[j].pc_point[endA][0] >=
pt_2d[0]) ||
- (polyA_2d.p_contour[j].pc_point[endA][0] <=
pt_2d[0] &&
- polyA_2d.p_contour[j].pc_point[beginA][0] >=
pt_2d[0]))) {
- ++npts_on_contour;
-
- if (polyA_2d.p_hole[j])
- winding = 0;
- else
- winding = 1;
-
- goto endA;
- }
-
- continue;
- }
-
- VSUB2(BmA, B, A);
- VSUB2(CmA, C, A);
- VUNITIZE(BmA);
- VUNITIZE(CmA);
- dot = VDOT(BmA, CmA);
-
- if (NEAR_EQUAL(dot, -1.0, tol_dist_sq) || NEAR_EQUAL(dot,
1.0, tol_dist_sq)) {
- ++npts_on_contour;
-
- if (polyA_2d.p_hole[j])
- winding = 0;
- else
- winding = 0;
-
- goto endA;
- }
-
- VCROSS(vcross, BmA, CmA);
-
- if (vcross[2] > 0)
- ++winding;
- }
- }
-
- endA:
- /* found a point on a polygon B contour that's outside of polygon A
*/
- if (!(winding%2)) {
- ++npts_outside;
- if (npts_outside != npts_on_contour) {
- break;
- }
- }
- }
-
- /* found a B polygon contour that's completely inside polygon A */
- if (winding%2 || (npts_outside != 0 &&
- npts_outside != polyB_2d.p_contour[i].pc_num_points &&
- npts_outside == npts_on_contour)) {
- ret = 1;
- goto end;
- }
- }
-
- for (i = 0; i < polyA_2d.p_num_contours; ++i) {
- size_t npts_on_contour = 0;
- size_t npts_outside = 0;
-
- /* Skip holes */
- if (polyA_2d.p_hole[i])
- continue;
-
- /* Check if all points in the current polygon A contour are inside B */
- for (beginA = 0; beginA < polyA_2d.p_contour[i].pc_num_points;
++beginA) {
- winding = 0;
- V2MOVE(pt_2d, polyA_2d.p_contour[i].pc_point[beginA]);
- V2MOVE(A, pt_2d);
- A[2] = 0.0;
-
- for (j = 0; j < polyB_2d.p_num_contours; ++j) {
- point_t B, C;
- vect_t BmA, CmA;
- vect_t vcross;
-
- for (beginB = 0; beginB < polyB_2d.p_contour[j].pc_num_points;
++beginB) {
- fastf_t dot;
-
- if (beginB == polyB_2d.p_contour[j].pc_num_points-1)
- endB = 0;
- else
- endB = beginB + 1;
-
- if (V2NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB],
pt_2d, tol_dist_sq) ||
- V2NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[endB],
pt_2d, tol_dist_sq)) {
- /* pt_2d is the same as one of the end points, so count
it */
-
- if (polyB_2d.p_hole[j])
- winding = 0;
- else
- winding = 1;
-
- ++npts_on_contour;
- goto endB;
- }
-
- if ((polyB_2d.p_contour[j].pc_point[beginB][1] <= pt_2d[1]
&&
- polyB_2d.p_contour[j].pc_point[endB][1] > pt_2d[1])) {
- V2MOVE(B, polyB_2d.p_contour[j].pc_point[endB]);
- B[2] = 0.0;
- V2MOVE(C, polyB_2d.p_contour[j].pc_point[beginB]);
- C[2] = 0.0;
- } else if ((polyB_2d.p_contour[j].pc_point[endB][1] <=
pt_2d[1] &&
- polyB_2d.p_contour[j].pc_point[beginB][1] >
pt_2d[1])) {
- V2MOVE(B, polyB_2d.p_contour[j].pc_point[beginB]);
- B[2] = 0.0;
- V2MOVE(C, polyB_2d.p_contour[j].pc_point[endB]);
- C[2] = 0.0;
- } else {
- /* check if the point is on a horizontal edge */
- if
(NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB][1],
- polyB_2d.p_contour[j].pc_point[endB][1],
tol_dist_sq) &&
-
NEAR_EQUAL(polyB_2d.p_contour[j].pc_point[beginB][1], pt_2d[1], tol_dist_sq) &&
- ((polyB_2d.p_contour[j].pc_point[beginB][0] <=
pt_2d[0] &&
- polyB_2d.p_contour[j].pc_point[endB][0] >=
pt_2d[0]) ||
- (polyB_2d.p_contour[j].pc_point[endB][0] <=
pt_2d[0] &&
- polyB_2d.p_contour[j].pc_point[beginB][0] >=
pt_2d[0]))) {
- if (polyB_2d.p_hole[j])
- winding = 0;
- else
- winding = 1;
-
- ++npts_on_contour;
-
- goto endB;
- }
-
- continue;
- }
-
- VSUB2(BmA, B, A);
- VSUB2(CmA, C, A);
- VUNITIZE(BmA);
- VUNITIZE(CmA);
- dot = VDOT(BmA, CmA);
-
- if (NEAR_EQUAL(dot, -1.0, tol_dist_sq) || NEAR_EQUAL(dot,
1.0, tol_dist_sq)) {
- if (polyB_2d.p_hole[j])
- winding = 0;
- else
- winding = 1;
-
- ++npts_on_contour;
- goto endB;
- }
-
- VCROSS(vcross, BmA, CmA);
-
- if (vcross[2] > 0)
- ++winding;
- }
- }
-
- endB:
- /* found a point on a polygon A contour that's outside of polygon B
*/
- if (!(winding%2)) {
- ++npts_outside;
- if (npts_outside != npts_on_contour) {
- break;
- }
- }
- }
-
- /* found an A polygon contour that's completely inside polygon B */
- if (winding%2 || (npts_outside != 0 &&
- npts_outside != polyA_2d.p_contour[i].pc_num_points &&
- npts_outside == npts_on_contour)) {
- ret = 1;
- break;
- } else
- ret = 0;
- }
-
-end:
-
- for (i = 0; i < polyA->gp_num_contours; ++i)
- bu_free((void *)polyA_2d.p_contour[i].pc_point, "pc_point");
- for (i = 0; i < polyB->gp_num_contours; ++i)
- bu_free((void *)polyB_2d.p_contour[i].pc_point, "pc_point");
-
- bu_free((void *)polyA_2d.p_hole, "p_hole");
- bu_free((void *)polyA_2d.p_contour, "p_contour");
- bu_free((void *)polyB_2d.p_hole, "p_hole");
- bu_free((void *)polyB_2d.p_contour, "p_contour");
-
- return ret;
+ return polygons_overlap(polyA, polyB, gedp->ged_gvp->gv_model2view,
&gedp->ged_wdbp->wdb_tol, gedp->ged_gvp->gv_scale);
}
-
HIDDEN int
sort_by_X(const void *p1, const void *p2, void *UNUSED(arg))
{
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits