Revision: 56742
          http://sourceforge.net/p/brlcad/code/56742
Author:   phoenixyjll
Date:     2013-08-12 10:54:34 +0000 (Mon, 12 Aug 2013)
Log Message:
-----------
Implement a function to check the validity of the outer loop before adding a 
trimmed face.

Modified Paths:
--------------
    brlcad/trunk/src/libbrep/boolean.cpp

Modified: brlcad/trunk/src/libbrep/boolean.cpp
===================================================================
--- brlcad/trunk/src/libbrep/boolean.cpp        2013-08-11 11:07:00 UTC (rev 
56741)
+++ brlcad/trunk/src/libbrep/boolean.cpp        2013-08-12 10:54:34 UTC (rev 
56742)
@@ -87,39 +87,74 @@
 }
 
 
-HIDDEN int
-IsPointInsideLoop(const ON_2dPoint& pt, const ON_SimpleArray<ON_Curve*>& loop)
+HIDDEN bool
+IsLoopValid(const ON_SimpleArray<ON_Curve*>& loop, double tolerance, 
ON_PolyCurve* polycurve = NULL)
 {
-    // returns:
-    //   -1: the input is not a loop
-    //   0:  the point is not inside the loop or on boundary
-    //   1:  the point is inside the loop or on boundary
+    bool delete_curve = false;
+    bool ret = true;
 
     if (loop.Count() == 0) {
        bu_log("The input loop is empty.\n");
-       return -1;
+       ret = false;
     }
 
-    // First, use a ON_PolyCurve to represent the loop, and check the loop
-    // is continuous and closed or not.
-    ON_PolyCurve polycurve;
-    polycurve.Append(loop[0]->Duplicate());
-    for (int i = 1 ; i < loop.Count(); i++) {
-       if (loop[i] && loop[i - 1] && 
loop[i]->PointAtStart().DistanceTo(loop[i-1]->PointAtEnd()) < ON_ZERO_TOLERANCE)
-           polycurve.Append(loop[i]->Duplicate());
-       else {
-           bu_log("The input loop is not continuous.\n");
-           return -1;
+    // First, use a ON_PolyCurve to represent the loop.
+    if (ret) {
+       if (polycurve == NULL) {
+           polycurve = new ON_PolyCurve;
+           if (polycurve)
+               delete_curve = true;
+           else
+               ret = false;
        }
     }
-    if (!polycurve.IsClosed()) {
+
+    // Check the loop is continuous and closed or not.
+    if (ret) {
+       polycurve->Append(loop[0]->Duplicate());
+       for (int i = 1 ; i < loop.Count(); i++) {
+           if (loop[i] && loop[i - 1] && 
loop[i]->PointAtStart().DistanceTo(loop[i-1]->PointAtEnd()) < ON_ZERO_TOLERANCE)
+               polycurve->Append(loop[i]->Duplicate());
+           else {
+               bu_log("The input loop is not continuous.\n");
+               ret = false;
+           }
+       }
+    }
+    if (ret && !polycurve->IsClosed()) {
        bu_log("The input loop is not closed.\n");
-       return -1;
+       ret = false;
     }
 
+    if (ret) {
+       // Check whether the loop is degenerated.
+       ON_BoundingBox bbox = polycurve->BoundingBox();
+       ret = !ON_NearZero(bbox.Diagonal().Length(), tolerance)
+             && !polycurve->IsLinear(tolerance);
+    }
+
+    if (delete_curve)
+       delete polycurve;
+
+    return ret;
+}
+
+
+HIDDEN int
+IsPointInsideLoop(const ON_2dPoint& pt, const ON_SimpleArray<ON_Curve*>& loop)
+{
+    // returns:
+    //   -1: the input is not a valid loop
+    //   0:  the point is not inside the loop or on boundary
+    //   1:  the point is inside the loop or on boundary
+
+    ON_PolyCurve polycurve;
+    if (!IsLoopValid(loop, ON_ZERO_TOLERANCE, &polycurve))
+       return -1;
+
     ON_BoundingBox bbox = polycurve.BoundingBox();
     if (!bbox.IsPointIn(pt))
-       return false;
+       return 0;
 
     // The input point is inside the loop's bounding box.
     // out must be outside the closed region (and the bbox).
@@ -430,10 +465,13 @@
        }
 
        // Append a trimmed face with newloop as its outerloop
-       TrimmedFace *newface = new TrimmedFace();
-       newface->face = in->face;
-       newface->outerloop.Append(newloop.Count(), newloop.Array());
-       out.Append(newface);
+       // Don't add a face if the outerloop is not valid (e.g. degenerated).
+       if (IsLoopValid(newloop, ON_ZERO_TOLERANCE)) {
+           TrimmedFace *newface = new TrimmedFace();
+           newface->face = in->face;
+           newface->outerloop.Append(newloop.Count(), newloop.Array());
+           out.Append(newface);
+       }
     }
 
     // Remove the duplicated segments before the first intersection point.
@@ -446,12 +484,14 @@
        out.Append(in->Duplicate());
     } else {
        // The remaining part after splitting some parts out.
-       TrimmedFace *newface = new TrimmedFace();
-       newface->face = in->face;
-       newface->outerloop = outerloop;
-       newface->innerloop = in->innerloop;
-       newface->innerloop.insert(newface->innerloop.end(), innerloops.begin(), 
innerloops.end());
-       out.Append(newface);
+       if (IsLoopValid(outerloop, ON_ZERO_TOLERANCE)) {
+           TrimmedFace *newface = new TrimmedFace();
+           newface->face = in->face;
+           newface->outerloop = outerloop;
+           newface->innerloop = in->innerloop;
+           newface->innerloop.insert(newface->innerloop.end(), 
innerloops.begin(), innerloops.end());
+           out.Append(newface);
+       }
     }
 
     bu_log("Split to %d faces.\n", out.Count());

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead. 
Download for free and get started troubleshooting in minutes. 
http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to