Revision: 55941
          http://sourceforge.net/p/brlcad/code/55941
Author:   phoenixyjll
Date:     2013-07-03 04:43:06 +0000 (Wed, 03 Jul 2013)
Log Message:
-----------
The surface tree could be reused - avoid generating the surface tree again and 
again. And add some special splitting machanism for polylines.

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

Modified: brlcad/trunk/include/brep.h
===================================================================
--- brlcad/trunk/include/brep.h 2013-07-02 19:13:33 UTC (rev 55940)
+++ brlcad/trunk/include/brep.h 2013-07-03 04:43:06 UTC (rev 55941)
@@ -1948,6 +1948,9 @@
  *   surfaceB_vdomain - [in]
  *     optional restriction on surfaceB v domain
  *
+ *   tree - [in]
+ *     optional surface tree for surfaceB, to avoid re-computation
+ *
  * Returns:
  *    True for an intersection. False for no intersection.
  */
@@ -1957,7 +1960,8 @@
             ON_ClassArray<ON_PX_EVENT>& x,
             double tolerance = 0.0,
             const ON_Interval* surfaceB_udomain = 0,
-            const ON_Interval* surfaceB_vdomain = 0);
+            const ON_Interval* surfaceB_vdomain = 0,
+            brlcad::SurfaceTree* tree = 0);
 
 /**
  * An overload of ON_Intersect for curve-curve intersection.

Modified: brlcad/trunk/src/libbrep/intersect.cpp
===================================================================
--- brlcad/trunk/src/libbrep/intersect.cpp      2013-07-02 19:13:33 UTC (rev 
55940)
+++ brlcad/trunk/src/libbrep/intersect.cpp      2013-07-03 04:43:06 UTC (rev 
55941)
@@ -75,14 +75,18 @@
     {
        for (int i = 0; i < 2; i++)
            m_children[i] = new Subcurve();
-
-       if (m_curve->Split(m_t.Mid(), m_children[0]->m_curve, 
m_children[1]->m_curve) == false)
+       ON_SimpleArray<double> pline_t;
+       double split_t = m_t.Mid();
+       if (m_curve->IsPolyline(NULL, &pline_t) && pline_t.Count() > 2) {
+           split_t = pline_t[pline_t.Count()/2];
+       }
+       if (m_curve->Split(split_t, m_children[0]->m_curve, 
m_children[1]->m_curve) == false)
            return -1;
 
-       m_children[0]->m_t = ON_Interval(m_t.Min(), m_t.Mid());
+       m_children[0]->m_t = m_children[0]->m_curve->Domain();
        m_children[0]->SetBBox(m_children[0]->m_curve->BoundingBox());
        m_children[0]->m_islinear = m_children[0]->m_curve->IsLinear();
-       m_children[1]->m_t = ON_Interval(m_t.Mid(), m_t.Max());
+       m_children[1]->m_t = m_children[1]->m_curve->Domain();
        m_children[1]->SetBBox(m_children[1]->m_curve->BoundingBox());
        m_children[1]->m_islinear = m_children[1]->m_curve->IsLinear();
 
@@ -154,14 +158,14 @@
            m_children[i] = new Subsurface();
        ON_Surface *temp_surf1 = NULL, *temp_surf2 = NULL;
        ON_BOOL32 ret = true;
-       ret = m_surf->Split(0, m_u.Mid(), temp_surf1, temp_surf2);
+       ret = m_surf->Split(0, m_surf->Domain(0).Mid(), temp_surf1, temp_surf2);
        if (!ret) {
            delete temp_surf1;
            delete temp_surf2;
            return -1;
        }
 
-       ret = temp_surf1->Split(1, m_v.Mid(), m_children[0]->m_surf, 
m_children[1]->m_surf);
+       ret = temp_surf1->Split(1, m_surf->Domain(1).Mid(), 
m_children[0]->m_surf, m_children[1]->m_surf);
        delete temp_surf1;
        if (!ret) {
            delete temp_surf2;
@@ -443,7 +447,8 @@
             ON_ClassArray<ON_PX_EVENT>& x,
             double tolerance,
             const ON_Interval* surfaceB_udomain,
-            const ON_Interval* surfaceB_vdomain)
+            const ON_Interval* surfaceB_vdomain,
+            brlcad::SurfaceTree* tree)
 {
     if (tolerance <= 0.0)
        tolerance = PSI_DEFAULT_TOLERANCE;
@@ -464,15 +469,19 @@
     brep->AddSurface(surfaceB.Duplicate());
     brep->NewFace(0);
     ON_2dPoint closest_point_uv;
-    brlcad::SurfaceTree *tree = new brlcad::SurfaceTree(brep->Face(0), false, 
MAX_PSI_DEPTH);
+    bool delete_tree = false;
+    if (!tree) {
+       tree = new brlcad::SurfaceTree(brep->Face(0), false, MAX_PSI_DEPTH);
+       delete_tree = true;
+    }
     if (brlcad::get_closest_point(closest_point_uv, brep->Face(0), pointA, 
tree) == false) {
        delete brep;
-       delete tree;
+       if (delete_tree) delete tree;
        return false;
     }
 
     delete brep;
-    delete tree;
+    if (delete_tree) delete tree;
 
     ON_3dPoint closest_point_3d = surfaceB.PointAt(closest_point_uv.x, 
closest_point_uv.y);
     if (pointA.DistanceTo(closest_point_3d) <= tolerance
@@ -560,7 +569,7 @@
 
 
 void
-newton_cci(double& t_a, double& t_b, const ON_Curve* curveA, const ON_Curve* 
curveB)
+newton_cci(double& t_a, double& t_b, const ON_Curve* curveA, const ON_Curve* 
curveB, double intersection_tolerance)
 {
     // Equations:
     //   x_a(t_a) - x_b(t_b) = 0
@@ -572,6 +581,9 @@
     double last_t_a = DBL_MAX*.5, last_t_b = DBL_MAX*.5;
     ON_3dPoint pointA = curveA->PointAt(t_a);
     ON_3dPoint pointB = curveB->PointAt(t_b);
+    if (pointA.DistanceTo(pointB) < intersection_tolerance)
+       return;
+
     int iteration = 0;
     while (fabs(last_t_a - t_a) + fabs(last_t_b - t_b) > ON_ZERO_TOLERANCE
           && iteration++ < CCI_MAX_ITERATIONS) {
@@ -753,9 +765,9 @@
            // may miss some overlap cases. (Overlap events can also converge 
to one
            // point)
            double t_a1 = i->first->m_t.Min(), t_b1 = i->second->m_t.Min();
-           newton_cci(t_a1, t_b1, curveA, curveB);
+           newton_cci(t_a1, t_b1, curveA, curveB, intersection_tolerance);
            double t_a2 = i->first->m_t.Max(), t_b2 = i->second->m_t.Max();
-           newton_cci(t_a2, t_b2, curveA, curveB);
+           newton_cci(t_a2, t_b2, curveA, curveB, intersection_tolerance);
 
            ON_3dPoint pointA1 = curveA->PointAt(t_a1);
            ON_3dPoint pointB1 = curveB->PointAt(t_b1);
@@ -1010,7 +1022,7 @@
 
 
 void
-newton_csi(double& t, double& u, double& v, const ON_Curve* curveA, const 
ON_Surface* surfB)
+newton_csi(double& t, double& u, double& v, const ON_Curve* curveA, const 
ON_Surface* surfB, double intersection_tolerance, brlcad::SurfaceTree* 
UNUSED(tree))
 {
     // Equations:
     //   x_a(t) - x_b(u,v) = 0
@@ -1020,6 +1032,9 @@
     double last_t = DBL_MAX/3, last_u = DBL_MAX/3, last_v = DBL_MAX/3;
     ON_3dPoint pointA = curveA->PointAt(t);
     ON_3dPoint pointB = surfB->PointAt(u, v);
+    if (pointA.DistanceTo(pointB) < intersection_tolerance)
+       return;
+
     int iteration = 0;
     while (fabs(last_t - t) + fabs(last_u - u) + fabs(last_v - v) > 
ON_ZERO_TOLERANCE
           && iteration++ < CCI_MAX_ITERATIONS) {
@@ -1069,6 +1084,15 @@
     if (overlap_tolerance <= 0.0)
        overlap_tolerance = 2*intersection_tolerance;
 
+    // We need ON_BrepFace for get_closest_point().
+    // This is used in point-surface intersections, in case we build the
+    // tree again and again.
+    ON_Brep *brep = ON_Brep::New();
+    brep->AddSurface(surfaceB->Duplicate());
+    brep->NewFace(0);
+    ON_2dPoint closest_point_uv;
+    brlcad::SurfaceTree *tree = new brlcad::SurfaceTree(brep->Face(0), false, 
MAX_PSI_DEPTH);
+
     Subcurve rootA;
     Subsurface rootB;
     if (!build_curve_root(curveA, curveA_domain, rootA))
@@ -1139,7 +1163,7 @@
                        // First, we check the endpoints of the line segment
                        ON_ClassArray<ON_PX_EVENT> px_event1, px_event2;
                        int intersections = 0;
-                       if (ON_Intersect(line.from, *surfaceB, px_event1)) {
+                       if (ON_Intersect(line.from, *surfaceB, px_event1, 
intersection_tolerance, 0, 0, tree)) {
                            Event->m_A[intersections] = line.from;
                            Event->m_B[intersections] = px_event1[0].m_B;
                            Event->m_a[intersections] = i->first->m_t.Min();
@@ -1147,7 +1171,7 @@
                            Event->m_b[2*intersections+1] = px_event1[0].m_b[1];
                            intersections++;
                        }
-                       if (ON_Intersect(line.to, *surfaceB, px_event2)) {
+                       if (ON_Intersect(line.to, *surfaceB, px_event2, 
intersection_tolerance, 0, 0, tree)) {
                            Event->m_A[intersections] = line.to;
                            Event->m_B[intersections] = px_event2[0].m_B;
                            Event->m_a[intersections] = i->first->m_t.Max();
@@ -1245,7 +1269,7 @@
                    ON_3dPoint intersection = line.from + 
line.Direction()*line_t;
                    ON_2dPoint uv;
                    ON_ClassArray<ON_PX_EVENT> px_event;
-                   if (!ON_Intersect(intersection, *(i->second->m_surf), 
px_event))
+                   if (!ON_Intersect(intersection, *(i->second->m_surf), 
px_event, intersection_tolerance, 0, 0, tree))
                        continue;
                    
                    ON_X_EVENT* Event = new ON_X_EVENT;
@@ -1271,10 +1295,10 @@
        // point)
        double u1 = i->second->m_u.Mid(), v1 = i->second->m_v.Mid();
        double t1 = i->first->m_t.Min();
-       newton_csi(t1, u1, v1, curveA, surfaceB);
+       newton_csi(t1, u1, v1, curveA, surfaceB, intersection_tolerance, tree);
        double u2 = i->second->m_u.Mid(), v2 = i->second->m_v.Mid();
        double t2 = i->first->m_t.Max();
-       newton_csi(t2, u2, v2, curveA, surfaceB);
+       newton_csi(t2, u2, v2, curveA, surfaceB, intersection_tolerance, tree);
 
        if (isnan(u1) || isnan(v1) || isnan(t1)) {
            u1 = u2; v1 = v2; t1 = t2;
@@ -1341,7 +1365,7 @@
                    ON_3dPoint test_point = curveA->PointAt(t1 + 
(t2-t1)*j*strike);
                    ON_ClassArray<ON_PX_EVENT> psi_x;
                    // Use point-surface intersection
-                   if (!ON_Intersect(test_point, *surfaceB, psi_x, 
overlap_tolerance))
+                   if (!ON_Intersect(test_point, *surfaceB, psi_x, 
overlap_tolerance, 0, 0, tree))
                        break;
                }
                if (j == CSI_OVERLAP_TEST_POINTS) {

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


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to