Revision: 56173
          http://sourceforge.net/p/brlcad/code/56173
Author:   phoenixyjll
Date:     2013-07-22 04:48:02 +0000 (Mon, 22 Jul 2013)
Log Message:
-----------
Eliminate the bounding boxes completely inside the overlap region, and 
intersection points inside the overlaps.

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

Modified: brlcad/trunk/src/libbrep/intersect.cpp
===================================================================
--- brlcad/trunk/src/libbrep/intersect.cpp      2013-07-21 20:53:13 UTC (rev 
56172)
+++ brlcad/trunk/src/libbrep/intersect.cpp      2013-07-22 04:48:02 UTC (rev 
56173)
@@ -2101,6 +2101,106 @@
 }
 
 
+struct OverlapEvent {
+    ON_SSX_EVENT* m_event;  // Use pointer to the ON_SSX_EVENT in case that
+                           // ~ON_SSX_EVENT() is called.
+    ON_BoundingBox m_bboxA; // 2D surfA bounding box of the closed region.
+    enum TYPE {
+       undefined = 0,
+       outer = 1,
+       inner = 2
+    } m_type;
+
+    OverlapEvent() {}
+
+    OverlapEvent(ON_SSX_EVENT* _e) : m_event(_e)
+    {
+       m_type = undefined;
+       m_bboxA = _e->m_curveA->BoundingBox();
+    }
+
+    bool IsPointOnBoundary(const ON_2dPoint& _pt) {
+       ON_ClassArray<ON_PX_EVENT> px_event;
+       return ON_Intersect(ON_3dPoint(_pt), *(m_event->m_curveA), px_event);
+    }
+
+    // Test whether a point is inside the closed region (including boundary).
+    // Approach: Use line-curve intersections. If the line between this point
+    // and a point outside the b-box has an odd number of intersections with
+    // the boundary, it's considered inside, otherwise outside. (Tangent
+    // intersection are counted 2.)
+    bool IsPointIn(const ON_2dPoint& _pt) {
+       if (!m_bboxA.IsPointIn(_pt))
+           return false;
+       if (IsPointOnBoundary(_pt))
+           return true;
+       ON_ClassArray<ON_PX_EVENT> px_event;
+       // This point must be outside the closed region.
+       ON_2dPoint out = _pt + ON_2dVector(m_bboxA.Diagonal());
+       ON_LineCurve linecurve(_pt, out);
+       ON_SimpleArray<ON_X_EVENT> x_event;
+       ON_Intersect(&linecurve, m_event->m_curveA, x_event);
+       int count = x_event.Count();
+       for (int i = 0; i < x_event.Count(); i++) {
+           // Find tangent intersections.
+           // What should we do if it's ccx_overlap?
+           if 
(m_event->m_curveA->TangentAt(x_event[i].m_a[0]).IsParallelTo(linecurve.m_line.Direction()))
+               count++;
+       }
+       return count % 2 ? true : false;
+    }
+
+    // Return false if the point is on the boundary.
+    bool IsPointOut(const ON_2dPoint& _pt) {
+       return !IsPointIn(_pt);
+    }
+
+    // Test whether there are intersections between the box boundaries
+    // and the boundary curve.
+    // If there are not intersection, there can be 3 cases:
+    // 1) The box is completely in.
+    // 2) The box is completely out.
+    // 3) The box completely contains the closed region bounded by that curve.
+    bool IsBoxIntersected(const ON_2dPoint& _min, const ON_2dPoint& _max) {
+       ON_2dPoint corner[4] = {
+           _min,
+           ON_2dPoint(_max.x, _min.y),
+           _max,
+           ON_2dPoint(_min.x, _max.y)
+       };
+       ON_LineCurve linecurve[4] = {
+           ON_LineCurve(corner[0], corner[1]),
+           ON_LineCurve(corner[1], corner[2]),
+           ON_LineCurve(corner[2], corner[3]),
+           ON_LineCurve(corner[3], corner[0])
+       };
+       ON_SimpleArray<ON_X_EVENT> x_event[4];
+       for (int i = 0; i < 4; i++) {
+           if (ON_Intersect(&linecurve[i], m_event->m_curveA, x_event[i]))
+               return true;
+       }
+       return false;
+    }
+
+    bool IsBoxCompletelyIn(const ON_2dPoint& _min, const ON_2dPoint& _max) {
+       // There should not be intersections between the box boundaries
+       // and the boundary curve.
+       if (IsBoxIntersected(_min, _max)) {
+           return false;
+       }
+       ON_2dPoint center = (_min + _max) * 0.5;
+       return m_bboxA.Includes(ON_BoundingBox(_min, _max)) && 
IsPointIn(center);
+    }
+
+    bool IsBoxCompletelyOut(const ON_2dPoint& _min, const ON_2dPoint& _max) {
+       if (IsBoxIntersected(_min, _max))
+           return false;
+       ON_2dPoint center = (_min + _max) * 0.5;
+       return !IsPointIn(center) && !ON_BoundingBox(_min, 
_max).Includes(m_bboxA);
+    }
+};
+
+
 int
 ON_Intersect(const ON_Surface* surfA,
             const ON_Surface* surfB,
@@ -2293,7 +2393,13 @@
        }
     }
 
+    // Generate OverlapEvents.
+    ON_SimpleArray<OverlapEvent> overlapevents;
     for (int i = 0; i < x.Count(); i++) {
+       overlapevents.Append(OverlapEvent(&x[i]));
+    }
+
+    for (int i = 0; i < x.Count(); i++) {
        // The overlap region should be to the LEFT of that *m_curveA*.
        // (See opennurbs/opennurbs_x.h)
        double midA = x[i].m_curveA->Domain().Mid();
@@ -2357,13 +2463,14 @@
            x[i].m_curve3d->Reverse();
            x[i].m_curveA->Reverse();
            x[i].m_curveB->Reverse();
+           overlapevents[i].m_type = OverlapEvent::inner;
+       } else {
+           // The test point inside that region is an overlap point.
+           overlapevents[i].m_type = OverlapEvent::outer;
        }
     }
 
-    // Just for debugging use.
-    // After more later work on overlaps, this must be removed.
-    if (x.Count()) return x.Count();
-
+    bu_log("%d overlap events.\n", overlapevents.Count());
     /* Second step: calculate the intersection of the bounding boxes.
      * Only the children of intersecting b-box pairs need to be considered.
      * The children will be generated only when they are needed, using the
@@ -2375,6 +2482,34 @@
            break;
        next_candidates.clear();
        for (NodePairs::iterator i = candidates.begin(); i != candidates.end(); 
i++) {
+           // If the box is considered already belonging to the overlap
+           // regions, we don't need to further sub-divide it.
+           ON_2dPoint min2d(i->first->m_u.Min(), i->first->m_v.Min());
+           ON_2dPoint max2d(i->first->m_u.Max(), i->first->m_v.Max());
+           bool out_of_all_inner = true, inside_one_outer = false;
+           for (int j = 0; j < overlapevents.Count(); j++) {
+               if (overlapevents[j].m_type == OverlapEvent::inner
+                   && !overlapevents[j].IsBoxCompletelyOut(min2d, max2d)) {
+                   out_of_all_inner = false;
+                   break;
+               }
+           }
+           if (out_of_all_inner) {
+               // It's completely out of all inner loops.
+               for (int j = 0; j < overlapevents.Count(); j++) {
+                   if (overlapevents[j].m_type == OverlapEvent::outer
+                       && overlapevents[j].IsBoxCompletelyIn(min2d, max2d)) {
+                       inside_one_outer = true;
+                       break;
+                   }
+               }
+               // We only do this optimization of surfA, because node pairs
+               // need both boxes from surfA and surfB, and eliminate one of
+               // them is enough.
+               if (inside_one_outer) {
+                   continue;
+               }
+           }
            std::vector<Subsurface*> splittedA, splittedB;
            if ((*i).first->Split() != 0) {
                splittedA.push_back((*i).first);
@@ -2512,9 +2647,35 @@
                && tmp_curvest[i].DistanceTo(curvest[j]) < 
intersection_tolerance_B)
                break;
        if (j == curvept.Count()) {
-           curvept.Append(tmp_curvept[i]);
-           curveuv.Append(tmp_curveuv[i]);
-           curvest.Append(tmp_curvest[i]);
+           // Test whether this point belongs to the overlap regions.
+           bool outside_inner = true, inside_outer = false;
+           for (int k = 0; k < overlapevents.Count(); k++) {
+               if (overlapevents[k].m_type == OverlapEvent::inner
+                   && overlapevents[k].IsPointIn(tmp_curveuv[i])
+                   && !overlapevents[k].IsPointOnBoundary(tmp_curveuv[i])) {
+                   // This point is strictly inside the inner loop,
+                   // so it doesn't belong to overlap regions.
+                   outside_inner = false;
+                   break;
+               }
+           }
+           if (outside_inner) {
+               // This point is out of all inner loops. If it's inside
+               // one outer loop (including on boundaries), it should
+               // belong to overlap regions.
+               for (int k = 0; k < overlapevents.Count(); k++) {
+                   if (overlapevents[k].m_type == OverlapEvent::outer
+                       && overlapevents[k].IsPointIn(tmp_curveuv[i])) {
+                       inside_outer = true;
+                       break;
+                   }
+               }
+           }
+           if (!inside_outer) {
+               curvept.Append(tmp_curvept[i]);
+               curveuv.Append(tmp_curveuv[i]);
+               curvest.Append(tmp_curvest[i]);
+           }
        }
     }
     bu_log("%d points on the intersection curves.\n", curvept.Count());

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


------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to