Revision: 45728
http://brlcad.svn.sourceforge.net/brlcad/?rev=45728&view=rev
Author: r_weiss
Date: 2011-07-28 22:53:26 +0000 (Thu, 28 Jul 2011)
Log Message:
-----------
Updated the prototype version of function 'nmg_triangulate_fu' within file
'nmg_tri.c'. The logic was simplified and code cleanup was done. This change is
disabled by default. This is a work in progress.
Modified Paths:
--------------
brlcad/trunk/src/librt/primitives/nmg/nmg_tri.c
Modified: brlcad/trunk/src/librt/primitives/nmg/nmg_tri.c
===================================================================
--- brlcad/trunk/src/librt/primitives/nmg/nmg_tri.c 2011-07-28 22:01:41 UTC
(rev 45727)
+++ brlcad/trunk/src/librt/primitives/nmg/nmg_tri.c 2011-07-28 22:53:26 UTC
(rev 45728)
@@ -3787,15 +3787,10 @@
nmg_triangulate_fu(struct faceuse *fu, const struct bn_tol *tol)
{
int ccw_result;
- int loopuse_count_before = 0;
- int loopuse_count_tmp = 0;
- int edgeuse_vert_count = 0;
- int vert_count;
+ int vert_count = 0;
/* boolean variables */
- int fu_done = 0;
- int lu_done = 0;
- int run_cut = 0;
+ int cut = 0;
int need_triangulation = 0;
struct bu_list *tbl2d;
@@ -3809,8 +3804,9 @@
BN_CK_TOL(tol);
NMG_CK_FACEUSE(fu);
+ NMG_GET_FU_NORMAL(fu_normal, fu);
+
if (rt_g.NMG_debug & DEBUG_TRI) {
- NMG_GET_FU_NORMAL(fu_normal, fu);
bu_log("---------------- Triangulate face fu_p = 0x%lx fu Normal = %g
%g %g\n",
(unsigned long)fu, V3ARGS(fu_normal));
}
@@ -3827,20 +3823,24 @@
need_triangulation = 0;
for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
NMG_CK_LOOPUSE(lu);
- edgeuse_vert_count = 0;
if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) {
continue;
}
- if (lu->orientation != OT_SAME) {
+ if (!((lu->orientation == OT_SAME) || (lu->orientation ==
OT_OPPOSITE))) {
+ bu_bomb("nmg_triangulate_fu(): loopuse orientation must be OT_SAME
or OT_OPPOSITE\n");
+ }
+ if (lu->orientation == OT_OPPOSITE) {
/* the faceuse must contain only exterior loopuse
* to possibly skip triangulation
*/
need_triangulation++;
} else {
+ vert_count = 0;
for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
- edgeuse_vert_count++;
+ NMG_CK_EDGEUSE(eu);
+ vert_count++;
}
- if (edgeuse_vert_count != 3) {
+ if (vert_count != 3) {
/* we want to process the loopuse if any have more
* or less than 3 vertices. if less than 3, we want
* to remove these loopuse, if greater than 3 we
@@ -3871,202 +3871,156 @@
*/
nmg_triangulate_rm_degen_loopuse(fu, tol);
- /* check to see if we need to triangulate this faceuse also test
- * that all loopuse to triangulate are either loopuse orientation
- * OT_SAME (outer loop) or OT_OPPOSITE (hole)
- */
- need_triangulation = 0;
- loopuse_count_tmp = 0;
- for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
- loopuse_count_tmp++;
- edgeuse_vert_count = 0;
- for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
- edgeuse_vert_count++;
- }
- if (edgeuse_vert_count < 3) {
- /* function nmg_triangulate_rm_degen_loopuse should have
- * removed all loopuse with < 3 vertices
- */
- bu_bomb("nmg_triangulate_fu(): missed removal of loopuse with < 3
vertices\n");
- } else {
- if (!((lu->orientation == OT_SAME) || (lu->orientation ==
OT_OPPOSITE))) {
- /* we can not triangulate a faceuse unless all loopuse
- * within this faceuse have a defined orientation of
- * either OT_SAME (outer loop) or OT_OPPOSITE (hole)
- */
- bu_bomb("nmg_triangulate_fu(): loopuse orientation not OT_SAME
or OT_OPPOSITE\n");
- }
- if (edgeuse_vert_count > 3) {
- need_triangulation++;
- }
- }
+ if (BU_LIST_IS_EMPTY(&fu->lu_hd)) {
+ /* faceuse contains no loopuse */
+ return;
}
- if (loopuse_count_tmp < 1) {
- /* if this happens, code should be added to cleanly remove
- * the faceuse without any loopuse
- */
- bu_bomb("nmg_triangulate_fu(): faceuse contains no loopuse\n");
- }
-
if (rt_g.NMG_debug & DEBUG_TRI) {
nmg_plot_fu("nmg_triangulate_fu_after_cleanup_after_degen_loopuse_killed", fu,
tol);
}
- vert_count = 0;
-
- if (!need_triangulation) {
- return;
- }
-
if (rt_g.NMG_debug & DEBUG_TRI) {
- NMG_GET_FU_NORMAL(fu_normal, fu);
- bu_log("---------------- proceeding to triangulate face %g %g %g\n",
V3ARGS(fu_normal));
+ bu_log("nmg_triangulate_fu(): proceeding to triangulate face %g %g
%g\n", V3ARGS(fu_normal));
}
- /* count loopuse */
- loopuse_count_before = 0;
- for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
- loopuse_count_before++;
- }
-
/* convert 3D face to face in the X-Y plane */
tbl2d = nmg_flatten_face(fu, TformMat);
- /* remove holes from faceuse */
+ if (rt_g.NMG_debug & DEBUG_TRI) {
+ validate_tbl2d("before nmg_triangulate_rm_holes", tbl2d, fu);
+ }
+
+ /* remove holes from faceuse. this is done by converting inner
+ * loopuse (i.e. holes, loopuse with cw rotation, loopuse with
+ * OT_OPPOSITE orientation) by joining/connecting these inner
+ * loopuse with outer loopuse so the inner loopuse becomes part
+ * of the outer loopuse
+ */
nmg_triangulate_rm_holes(fu, tbl2d, tol);
- /* the start of while-loop to perform cut_unimonotone */
- fu_done = 0;
- while(!fu_done) {
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- lu_done = 0;
- while(!lu_done) {
- run_cut = 0;
- if (BU_LIST_IS_HEAD(lu, &fu->lu_hd)) {
- lu_done = 1;
- } else if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC)
{
- /* block structure of logic allow skipping this condition
instead of bomb */
- bu_bomb("nmg_triangulate_fu(): found loopuse with no
vertexuse\n");
- } else {
- NMG_CK_LOOPUSE(lu);
- if (lu->orientation == OT_OPPOSITE) {
- /* block structure of logic allow skipping this condition
instead of bomb */
- if (1 || rt_g.NMG_debug & DEBUG_TRI) {
-
nmg_plot_fu("nmg_triangulate_fu_found_ot_opposite_loopuse", fu, tol);
+ if (rt_g.NMG_debug & DEBUG_TRI) {
+ validate_tbl2d("after nmg_triangulate_rm_holes", tbl2d, fu);
+ }
+
+ /* this 'while loop' goes through each loopuse within the faceuse
+ * and performs ear-clipping (i.e. triangulation). the 'while loop'
+ * ends when we can go through all the loopuse within the faceuse
+ * and no cuts need to be performed. each time a cut is performed
+ * we restart at the beginning of the list of loopuse. the reason
+ * for this is we can not be sure of the ordering of the loopuse
+ * within the faceuse after loopuse are cut.
+ */
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ vert_count = 0;
+ while(BU_LIST_NOT_HEAD(lu, &fu->lu_hd)) {
+ NMG_CK_LOOPUSE(lu);
+ cut = 0;
+ if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
+ /* true when loopuse contains edgeuse */
+ vert_count = 0;
+ for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
+ NMG_CK_EDGEUSE(eu);
+ vert_count++;
+ }
+ /* only ear-clip loopuse with > 3 vertices */
+ if (vert_count > 3) {
+ /* test loopuse rotation */
+ ccw_result = nmg_loop_is_ccw(lu, fu_normal, tol);
+ if (ccw_result == 1) {
+ /* true when loopuse rotation is ccw */
+ if (lu->orientation != OT_SAME) {
+ /* set loopuse orientation to OT_SAME */
+ nmg_set_lu_orientation(lu, 0);
}
- bu_log("nmg_triangulate_fu(): found OT_OPPOSITE loopuse
%lx, all should have been removed\n",
- (unsigned long)lu);
- bu_bomb("nmg_triangulate_fu(): found OT_OPPOSITE loopuse,
all should have been removed\n");
- } else {
- edgeuse_vert_count = 0;
+ /* ear clip loopuse */
+ cut_unimonotone(tbl2d, lu, tol);
+ cut = 1;
+ } else if (ccw_result == -1 || ccw_result == 0) {
+ /* true when loopuse rotation is cw or unknown */
+ bu_log("nmg_triangulate_fu(): lu = 0x%lx ccw_result =
%d\n",
+ (unsigned long)lu, ccw_result);
+ vert_count = 0;
for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
- edgeuse_vert_count++;
+ vert_count++;
+ bu_log("nmg_triangulate_fu(): %d ccw_result = %d lu =
%x coord = %g %g %g\n",
+ vert_count, ccw_result, lu,
V3ARGS(eu->vu_p->v_p->vg_p->coord));
}
- if (edgeuse_vert_count < 3) {
- /* block structure of logic allow skipping this
condition instead of bomb */
- bu_log("nmg_triangulate_fu(): found loopuse with < 3
vertices, all these loopuse should have been removed\n");
- } else if (edgeuse_vert_count == 3) {
- if (rt_g.NMG_debug & DEBUG_TRI) {
- bu_log("nmg_triangulate_fu(): skipping already
triangulated loopuse\n");
- }
- } else {
- /* loopuse contains > 3 vertices */
- NMG_GET_FU_NORMAL(fu_normal, fu);
- ccw_result = nmg_loop_is_ccw(lu, fu_normal, tol);
- if (ccw_result != 1) {
- bu_log("nmg_triangulate_fu(): lu_p = 0x%lx
ccw_result = %d, skipping loopuse\n",
- (unsigned long)lu, ccw_result);
- if (rt_g.NMG_debug & DEBUG_TRI) {
- edgeuse_vert_count = 0;
- for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
- edgeuse_vert_count++;
- bu_log("nmg_triangulate_fu(): unknown ccw,
vert %d lu_p = %x coord = %g %g %g\n",
- edgeuse_vert_count, lu,
V3ARGS(eu->vu_p->v_p->vg_p->coord));
- }
- }
- } else if (lu->orientation != OT_SAME) {
- /* block structure of logic allow skipping this
condition instead of bomb */
- /* the logic should have exited before this block
if the current loopuse
- * orientation is OT_OPPOSITE so if the current
loopuse is not OT_SAME
- * then the orientation is undefined and we can
not triangulate the
- * loopuse.
- */
- bu_bomb("nmg_triangulate_fu(): found non-OT_SAME
and non-OT_OPPOSITE loopuse, this should not happen\n");
- } else {
- /* perform cut */
- cut_unimonotone(tbl2d, lu, tol);
- run_cut = 1;
- }
- }
+ bu_bomb("nmg_triangulate_fu(): attempted to cut problem
loopuse\n");
+ } else {
+ bu_bomb("nmg_triangulate_fu(): function nmg_loop_is_ccw
returned invalid result\n");
}
}
- if (run_cut) {
- lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
- } else {
- lu = BU_LIST_PNEXT(loopuse, lu);
- }
- } /* close of while lu_done loop */
+ }
+ if (cut) {
+ /* since a cut was made, continue with the first
+ * loopuse in the faceuse
+ */
+ lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
+ } else {
+ /* since no cut was made, continue with the next
+ * loopuse in the faceuse
+ */
+ lu = BU_LIST_PNEXT(loopuse, lu);
+ }
+ } /* close of 'loopuse while loop' */
- /* the order the OT_SAME loopuse may be within the bu_list under the
faceuse
- * can not easily be predicted. the reason is because, as cuts are
performed, the
- * ordering of the list may change. therefore when the processing ends
of the
- * while lu_done loop, we may have missed some OT_SAME loopuse with
more than
- * 3 vertices, therefore we must test and re-start the lu_done loop if
any loopuse
- * still need triangulation.
+ if (1 || rt_g.NMG_debug & DEBUG_TRI) {
+ /* sanity check */
+ /* after triangulation, verify all loopuse contains <= 3 vertices
+ * and those loopuse with 3 vertices do not have a cw rotation
*/
-
- fu_done = 1;
for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
- if ((lu->orientation != OT_SAME) && (lu->orientation !=
OT_UNSPEC)) {
- /* There should be no OT_OPPOSITE loopuse remaining, some
loopuse may legitimately be
- * OT_UPSPEC in addition to OT_SAME but nothing else.
- */
- bu_bomb("nmg_triangulate_fu(): internal error, encountered
unexpected loopuse orientation\n");
- } else {
- edgeuse_vert_count = 0;
- for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
- edgeuse_vert_count++;
- if (edgeuse_vert_count > 3) {
- fu_done = 0;
- bu_log("nmg_triangulate_fu(): loop running
cut_unimonotone found remaining loopuse(s) with #verts > 3\n");
- break;
+ vert_count = 0;
+ for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
+ vert_count++;
+ if (vert_count > 3) {
+ bu_bomb("nmg_triangulate_fu(): after ear-clipping
found loopuse with > 3 vertices\n");
+ } else if (vert_count == 3) {
+ ccw_result = nmg_loop_is_ccw(lu, fu_normal, tol);
+ if (ccw_result == -1) {
+ bu_bomb("nmg_triangulate_fu(): after ear-clipping
found loopuse with cw rotation\n");
}
}
- if (edgeuse_vert_count != 3) {
- bu_log("nmg_triangulate_fu(): loop running
cut_unimonotone found remaining loopuse(s) with %d #verts != 3\n",
- edgeuse_vert_count);
- }
}
}
- if (fu_done == 0) {
- break;
- }
}
- if (fu_done == 0) {
- /* at this point all loopuse should have 3 or less vertices,
- * if this is not the case then we have a problem.
- */
- bu_bomb("nmg_triangulate_fu(): loop running cut_unimonotone found
unfinished loopuse.\n");
- }
- } /* close of while fu_done loop */
+ }
+ if (rt_g.NMG_debug & DEBUG_TRI) {
+ validate_tbl2d("nmg_triangulate_fu() after triangulation, before
lu_reorient", tbl2d, fu);
+ }
+
+ /* removes loopuse with < 3 vertices i.e. degenerate loopuse */
+ /* does not check if returning faceuse contains no loopuse */
+ nmg_triangulate_rm_degen_loopuse(fu, tol);
+
for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
+#if 1
+ /* set the loopuse orientation to OT_SAME */
+ nmg_set_lu_orientation(lu, 0);
+#else
+ /* compute and set the loopuse orientation within the loopuse
+ * based on the rotation of vertices within the loopuse and
+ * the faceuse normal. this may have problems with loopuse
+ * which enclose no area, i.e. loopuse with 3 vertices but the
+ * loopuse forms a straight line.
+ */
nmg_lu_reorient(lu);
+#endif
}
+ if (rt_g.NMG_debug & DEBUG_TRI) {
+ validate_tbl2d("nmg_triangulate_fu() after triangulation, after
lu_reorient", tbl2d, fu);
+ }
+
while (BU_LIST_WHILE(pt, pt2d, tbl2d)) {
BU_LIST_DEQUEUE(&pt->l);
bu_free((char *)pt, "pt2d free");
}
- bu_free((char *)tbl2d, "discard tbl2d");
- /* removes loopuse with < 3 vertices i.e. degenerate loopuse */
- /* does not check if returning faceuse contains no loopuse */
- nmg_triangulate_rm_degen_loopuse(fu, tol);
-
- return;
+ bu_free((char *)tbl2d, "discard tbl2d");
}
/* This is the 'else' to enable the prototype nmg_triangulate_fu
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Got Input? Slashdot Needs You.
Take our quick survey online. Come on, we don't ask for help often.
Plus, you'll get a chance to win $100 to spend on ThinkGeek.
http://p.sf.net/sfu/slashdot-survey
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits