Revision: 56232
          http://sourceforge.net/p/brlcad/code/56232
Author:   phoenixyjll
Date:     2013-07-26 12:47:22 +0000 (Fri, 26 Jul 2013)
Log Message:
-----------
Use a struct to represent the overlap segments. Split the curves with the 
intersection points (with other curves), so that we can get closed regions.

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

Modified: brlcad/trunk/src/libbrep/intersect.cpp
===================================================================
--- brlcad/trunk/src/libbrep/intersect.cpp      2013-07-26 04:50:16 UTC (rev 
56231)
+++ brlcad/trunk/src/libbrep/intersect.cpp      2013-07-26 12:47:22 UTC (rev 
56232)
@@ -2204,6 +2204,41 @@
 }
 
 
+struct OverlapSegment {
+    ON_Curve *m_curve3d, *m_curveA, *m_curveB;
+
+    int m_from;            // 0: iso-curve from A, 1: from B
+    int m_dir;     // 0: u iso-curve, 1: v iso-curve
+    double m_fix;   // the param fixed in the iso-curve
+                   // m_dir==0: m_fix==u; m_dir==1: m_fix==v
+    double m_min;   // minimum of the variable param in the iso-curve
+    double m_max;   // maximum of the variable param in the iso-curve
+
+    ON_2dPoint Get2DParam(double t)
+    {
+       return m_dir ? ON_2dPoint(t, m_fix) : ON_2dPoint(m_fix, t);
+    }
+
+    void SetCurvesToNull()
+    {
+       m_curve3d = m_curveA = m_curveB = NULL;
+    }
+
+    ~OverlapSegment()
+    {
+       if (m_curve3d)
+           delete m_curve3d;
+       m_curve3d = NULL;
+       if (m_curveA)
+           delete m_curveA;
+       m_curveA = NULL;
+       if (m_curveB)
+           delete m_curveB;
+       m_curveB = NULL;
+    }
+};
+
+
 struct OverlapEvent {
     ON_SSX_EVENT* m_event;  // Use pointer to the ON_SSX_EVENT in case that
                            // ~ON_SSX_EVENT() is called.
@@ -2397,13 +2432,11 @@
     // So we actually don't need to generate the Bezier patches explicitly,
     // and we can get the boundaries of them using IsoCurve() on knots.
 
-    ON_CurveArray overlaps, overlapA, overlapB;
+    ON_SimpleArray<OverlapSegment*> overlaps;
     for (int i = 0; i < 4; i++) {
        const ON_Surface* surf1 = i >= 2 ? surfB : surfA;
        const ON_Surface* surf2 = i >= 2 ? surfA : surfB;
        brlcad::SurfaceTree* tree = i >= 2 ? treeA : treeB;
-       ON_CurveArray& overlap1 = i >= 2 ? overlapB : overlapA;
-       ON_CurveArray& overlap2 = i >= 2 ? overlapA : overlapB;
        ON_2dPointArray& ptarray1 = i >= 2 ? tmp_curvest : tmp_curveuv;
        ON_2dPointArray& ptarray2 = i >= 2 ? tmp_curveuv : tmp_curvest;
        int dir = 1 - i%2;
@@ -2458,33 +2491,41 @@
                            double V2 = i%2 ? 
(x_event[k].m_a[0]+x_event[k].m_a[1])*0.5 : b_knots[j]+test_distance;
                            bool in1, in2;
                            ON_ClassArray<ON_PX_EVENT> px_event1, px_event2;
-                           in1 = ON_Intersect(surf1->PointAt(U1, V1), *surf2, 
px_event1, overlap_tolerance, 0, 0, tree);
+                           in1 = ON_Intersect(surf1->PointAt(U1, V1), *surf2, 
px_event1, 1e-5, 0, 0, tree);
                            if (in1) in1 &= surf1->NormalAt(U1, 
V1).IsParallelTo(surf2->NormalAt(px_event1[0].m_b[0], px_event1[0].m_b[1]));
-                           in2 = ON_Intersect(surf1->PointAt(U2, V2), *surf2, 
px_event2, overlap_tolerance, 0, 0, tree);
+                           in2 = ON_Intersect(surf1->PointAt(U2, V2), *surf2, 
px_event2, 1e-5, 0, 0, tree);
                            if (in2) in2 &= surf1->NormalAt(U2, 
V2).IsParallelTo(surf2->NormalAt(px_event2[0].m_b[0], px_event2[0].m_b[1]));
                            if ((in1 && !in2) || (!in1 && in2))
                                isvalid = true;
                        }
                        if (isvalid) {
                            // One side of it is shared and the other side is 
non-shared.
-                           overlaps.Append(sub_curve(boundary, 
x_event[k].m_a[0], x_event[k].m_a[1]));
-                           overlap1.Append(new ON_LineCurve(iso_pt1, iso_pt2));
-                           overlap2.Append(overlap2d[k]);
+                           OverlapSegment *seg = new OverlapSegment;
+                           seg->m_curve3d = sub_curve(boundary, 
x_event[k].m_a[0], x_event[k].m_a[1]);
+                           seg->m_curveA = new ON_LineCurve(iso_pt1, iso_pt2);
+                           seg->m_curveB = overlap2d[k];
+                           seg->m_dir = dir;
+                           seg->m_fix = b_knots[j];
+                           overlaps.Append(seg);
                            if (j == 0 && surf1->IsClosed(dir)) {
                                // something like close_domain().
                                // If the domain is closed, the iso-curve on the
                                // first knot and the last knot is the same, so
                                // we don't need to compute the intersections 
twice.
-                               
overlaps.Append((*overlaps.Last())->Duplicate());
                                iso_pt1.x = i%2 ? knots[knotcnt] : 
x_event[k].m_a[0];
                                iso_pt1.y = i%2 ? x_event[k].m_a[0] : 
knots[knotcnt];
                                iso_pt2.x = i%2 ? knots[knotcnt] : 
x_event[k].m_a[1];
                                iso_pt2.y = i%2 ? x_event[k].m_a[1] : 
knots[knotcnt];
-                               overlap1.Append(new ON_LineCurve(iso_pt1, 
iso_pt2));
-                               overlap2.Append(overlap2d[k]->Duplicate());
+                               seg->m_curve3d = 
(*overlaps.Last())->m_curve3d->Duplicate();
+                               seg->m_curveA = new ON_LineCurve(iso_pt1, 
iso_pt2);
+                               seg->m_curveB = overlap2d[k]->Duplicate();
+                               // seg.m_dir = dir;
+                               seg->m_fix = knots[knotcnt];
+                               overlaps.Append(seg);
                            }
                            // We set overlap2d[k] to NULL, is case that the 
curve
                            // is delete by the destructor of overlap2d. (See 
~ON_CurveArray())
+                           // Also the curves in seg. (See ~OverlapSegment())
                            overlap2d[k] = NULL;
                        }
                    }
@@ -2494,18 +2535,150 @@
        delete knots;
     }
 
+    int count_before = overlaps.Count();
+    // Not points, but a bundle of params:
+    // params[i] - the seperating params on overlaps[i]
+    // x - curve3d, y - curveA, z - curveB
+
+    ON_ClassArray<ON_3dPointArray> params(count_before);
+    for (int i = 0; i < count_before; i++) {
+       // Split the curves from the intersection points between them.
+       int count = params[i].Count();
+       for (int j = i + 1; j < count_before; j++) {
+           ON_SimpleArray<ON_X_EVENT> x_event;
+           ON_Intersect(overlaps[i]->m_curve3d, overlaps[j]->m_curve3d, 
x_event, intersection_tolerance);
+           count += x_event.Count();
+           for (int k = 0; k < x_event.Count(); k++) {
+               bu_log("intersections = %d\n", x_event.Count());
+               ON_3dPoint param;
+               ON_ClassArray<ON_PX_EVENT> e1, e2, e3, e4;
+               ON_2dPoint uv;
+               ON_2dPoint st;
+               if (brlcad::get_closest_point(uv, brepA->Face(0), 
x_event[k].m_A[0], treeA)
+                   && brlcad::get_closest_point(st, brepB->Face(0), 
x_event[k].m_B[0], treeB)) {
+                   // get_closest_point() have bugs. Before fixing it, we use 
this to detect an error and "fix" it.
+                   if (surfA->PointAt(uv.x, 
uv.y).DistanceTo(x_event[k].m_A[0]) > surfA->PointAt(st.x, 
st.y).DistanceTo(x_event[k].m_A[0]))
+                       uv = st;
+                   if (surfB->PointAt(st.x, 
st.y).DistanceTo(x_event[k].m_B[0]) > surfB->PointAt(uv.x, 
uv.y).DistanceTo(x_event[k].m_B[0]))
+                       st = uv;
+                   bu_log("lalaala %lf %lf %lf %lf\n", uv.x, uv.y, st.x, st.y);
+                   // Pull the 3D curve bace to the 2D space
+                   if (ON_Intersect(uv, *(overlaps[i]->m_curveA), e1, 
intersection_tolerance_A)
+                       && ON_Intersect(st, *(overlaps[i]->m_curveB), e2, 
intersection_tolerance_B)) {
+                       param.x = x_event[k].m_a[0];
+                       param.y = e1[0].m_b[0];
+                       param.z = e2[0].m_b[0];
+                       params[i].Append(param);
+                   }
+                   if (ON_Intersect(uv, *(overlaps[j]->m_curveA), e3, 
intersection_tolerance_A)
+                       && ON_Intersect(st, *(overlaps[j]->m_curveB), e4, 
intersection_tolerance_B)) {
+                       // The same routine for overlaps[j]
+                       param.x = x_event[k].m_b[0];
+                       param.y = e3[0].m_b[0];
+                       param.z = e4[0].m_b[0];
+                       params[j].Append(param);
+                   }
+               }
+               if (x_event[k].m_type == ON_X_EVENT::ccx_overlap) {
+                   ON_ClassArray<ON_PX_EVENT> psx3, psx4, e5, e6, e7, e8;
+                   if (ON_Intersect(x_event[k].m_A[0], *surfA, psx3, 
intersection_tolerance, 0, 0, treeA)
+                       && ON_Intersect(x_event[k].m_B[0], *surfB, psx4, 
intersection_tolerance, 0, 0, treeB)) {
+                       // Pull the 3D curve bace to the 2D space
+                       uv = psx3[0].m_b;
+                       st = psx4[0].m_b;
+                       if (ON_Intersect(x_event[k].m_A[1], 
*(overlaps[i]->m_curveA), e5, intersection_tolerance_A)
+                           && ON_Intersect(x_event[k].m_A[1], 
*(overlaps[i]->m_curveB), e6, intersection_tolerance_B)) {
+                           param.x = x_event[k].m_a[1];
+                           param.y = e5[0].m_b[0];
+                           param.z = e6[0].m_b[0];
+                           params[i].Append(param);
+                       }
+                       if (ON_Intersect(x_event[k].m_B[1], 
*(overlaps[j]->m_curveA), e7, intersection_tolerance_A)
+                           && ON_Intersect(x_event[k].m_B[1], 
*(overlaps[j]->m_curveB), e8, intersection_tolerance_B)) {
+                           // The same routine for overlaps[j]
+                           param.x = x_event[k].m_b[1];
+                           param.y = e7[0].m_b[0];
+                           param.z = e8[0].m_b[0];
+                           params[j].Append(param);
+                       }
+                   }
+               }
+           }
+       }
+       bu_log("\nparams[%d]=%d: ", i, params[i].Count());
+       for (int j = 0; j < params[i].Count(); j++) bu_log("%lf ", 
params[i][j].x);
+       if (count != params[i].Count()) {bu_log("count = %d\n", count); 
x.Empty(); return 0;}
+    }
+
+    for (int i = 0; i < count_before; i++) {
+       params[i].QuickSort(ON_CompareIncreasing);
+       int start = 0;
+       bool splitted = false;
+       for (int j = 1; j < params[i].Count(); j++) {
+           if (params[i][j].x - params[i][start].x < intersection_tolerance)
+               continue;
+           ON_Curve* subcurveA = sub_curve(overlaps[i]->m_curveA, 
params[i][start].y, params[i][j].y);
+           bool isvalid = false, isreversed = false;
+           double test_distance = 0.01;
+           // TODO: more sample points
+           ON_2dPoint UV1, UV2;
+           UV1 = UV2 = subcurveA->PointAt(subcurveA->Domain().Mid());
+           ON_3dVector normal = 
ON_CrossProduct(subcurveA->TangentAt(subcurveA->Domain().Mid()), ON_zaxis);
+           normal.Unitize();
+           UV1 -= normal*test_distance;        // left
+           UV2 += normal*test_distance;        // right
+           bool in1, in2;
+           ON_ClassArray<ON_PX_EVENT> px_event1, px_event2;
+           in1 = surfA->Domain(0).Includes(UV1.x)
+               && surfA->Domain(1).Includes(UV1.y)
+               && ON_Intersect(surfA->PointAt(UV1.x, UV1.y), *surfB, 
px_event1, 1e-5, 0, 0, treeB)
+               && surfA->NormalAt(UV1.x, 
UV1.y).IsParallelTo(surfB->NormalAt(px_event1[0].m_b[0], px_event1[0].m_b[1]));
+           in2 = surfA->Domain(0).Includes(UV2.x)
+               && surfA->Domain(1).Includes(UV2.y)
+               && ON_Intersect(surfA->PointAt(UV2.x, UV2.y), *surfB, 
px_event2, 1e-5, 0, 0, treeB)
+               && surfA->NormalAt(UV2.x, 
UV2.y).IsParallelTo(surfB->NormalAt(px_event2[0].m_b[0], px_event2[0].m_b[1]));
+           if (in1 && !in2)
+               isvalid = true;
+           else if (!in1 && in2) {
+               // the right side is overlapped.
+               isvalid = true;
+               isreversed = true;
+           }
+           if (isvalid) {
+               OverlapSegment *seg = new OverlapSegment;
+               seg->m_curve3d = sub_curve(overlaps[i]->m_curve3d, 
params[i][start].x, params[i][j].x);
+               seg->m_curveA = subcurveA;
+               seg->m_curveB = sub_curve(overlaps[i]->m_curveB, 
params[i][start].z, params[i][j].z);
+               if (isreversed) {
+                   seg->m_curve3d->Reverse();
+                   seg->m_curveA->Reverse();
+                   seg->m_curveB->Reverse();
+               }
+               seg->m_dir = overlaps[i]->m_dir;
+               seg->m_fix = overlaps[i]->m_fix;
+               overlaps.Append(seg);
+           }
+           start = j;
+           splitted = true;
+       }
+       if (splitted) {
+           delete overlaps[i];
+           overlaps[i] = NULL;
+       }
+    }
+
     for (int i = 0; i < overlaps.Count(); i++) {
-       if (!overlaps[i] || !overlapA[i] || !overlapB[i])
+       if (!overlaps[i] || !overlaps[i]->m_curveA || !overlaps[i]->m_curveB || 
!overlaps[i]->m_curve3d)
            continue;
 
        for (int j = 0; j <= overlaps.Count(); j++) {
-           if (overlaps[i]->IsClosed() && overlapA[i]->IsClosed() && 
overlapB[i]->IsClosed()) {
+           if (overlaps[i]->m_curve3d->IsClosed() && 
overlaps[i]->m_curveA->IsClosed() && overlaps[i]->m_curveB->IsClosed()) {
                // The i-th curve is close loop, we get a complete boundary of
                // that overlap region.
                ON_SSX_EVENT Event;
-               Event.m_curve3d = overlaps[i];
-               Event.m_curveA = overlapA[i];
-               Event.m_curveB = overlapB[i];
+               Event.m_curve3d = overlaps[i]->m_curve3d;
+               Event.m_curveA = overlaps[i]->m_curveA;
+               Event.m_curveB = overlaps[i]->m_curveB;
                Event.m_type = ON_SSX_EVENT::ssx_overlap;
                // Normalize the curves
                Event.m_curve3d->SetDomain(ON_Interval(0.0, 1.0));
@@ -2515,45 +2688,46 @@
                // Set the curves to NULL in case that they are deleted by
                // ~ON_SSX_EVENT() or ~ON_CurveArray().
                Event.m_curve3d = Event.m_curveA = Event.m_curveB = NULL;
-               overlaps[i] = overlapA[i] = overlapB[i] = NULL;
+               overlaps[i]->SetCurvesToNull();
+               overlaps[i] = NULL;
                break;
            }
 
-           if (j == overlaps.Count() || j == i || !overlaps[j] || !overlapA[j] 
|| !overlapB[j])
+           if (j == overlaps.Count() || j == i || !overlaps[j] || 
!overlaps[j]->m_curveA || !overlaps[j]->m_curveB || !overlaps[j]->m_curve3d)
                continue;
 
            // Merge the curves that link together.
-           if 
(overlaps[i]->PointAtStart().DistanceTo(overlaps[j]->PointAtEnd()) < 
intersection_tolerance
-               && 
overlapA[i]->PointAtStart().DistanceTo(overlapA[j]->PointAtEnd()) < 
intersection_tolerance_A
-               && 
overlapB[i]->PointAtStart().DistanceTo(overlapB[j]->PointAtEnd()) < 
intersection_tolerance_B) {
+           if 
(overlaps[i]->m_curve3d->PointAtStart().DistanceTo(overlaps[j]->m_curve3d->PointAtEnd())
 < intersection_tolerance
+               && 
overlaps[i]->m_curveA->PointAtStart().DistanceTo(overlaps[j]->m_curveA->PointAtEnd())
 < intersection_tolerance_A
+               && 
overlaps[i]->m_curveB->PointAtStart().DistanceTo(overlaps[j]->m_curveB->PointAtEnd())
 < intersection_tolerance_B) {
                // end -- start -- end -- start
-               overlaps[i] = link_curves(overlaps[j], overlaps[i]);
-               overlapA[i] = link_curves(overlapA[j], overlapA[i]);
-               overlapB[i] = link_curves(overlapB[j], overlapB[i]);
-           } else if 
(overlaps[i]->PointAtEnd().DistanceTo(overlaps[j]->PointAtStart()) < 
intersection_tolerance
-                      && 
overlapA[i]->PointAtEnd().DistanceTo(overlapA[j]->PointAtStart()) < 
intersection_tolerance_A
-                      && 
overlapB[i]->PointAtEnd().DistanceTo(overlapB[j]->PointAtStart()) < 
intersection_tolerance_B) {
+               overlaps[i]->m_curve3d = link_curves(overlaps[j]->m_curve3d, 
overlaps[i]->m_curve3d);
+               overlaps[i]->m_curveA = link_curves(overlaps[j]->m_curveA, 
overlaps[i]->m_curveA);
+               overlaps[i]->m_curveB = link_curves(overlaps[j]->m_curveB, 
overlaps[i]->m_curveB);
+           } else if 
(overlaps[i]->m_curve3d->PointAtEnd().DistanceTo(overlaps[j]->m_curve3d->PointAtStart())
 < intersection_tolerance
+                      && 
overlaps[i]->m_curveA->PointAtEnd().DistanceTo(overlaps[j]->m_curveA->PointAtStart())
 < intersection_tolerance_A
+                      && 
overlaps[i]->m_curveB->PointAtEnd().DistanceTo(overlaps[j]->m_curveB->PointAtStart())
 < intersection_tolerance_B) {
                // start -- end -- start -- end
-               overlaps[i] = link_curves(overlaps[i], overlaps[j]);
-               overlapA[i] = link_curves(overlapA[i], overlapA[j]);
-               overlapB[i] = link_curves(overlapB[i], overlapB[j]);
-           } else if 
(overlaps[i]->PointAtStart().DistanceTo(overlaps[j]->PointAtStart()) < 
intersection_tolerance
-                      && 
overlapA[i]->PointAtStart().DistanceTo(overlapA[j]->PointAtStart()) < 
intersection_tolerance_A
-                      && 
overlapB[i]->PointAtStart().DistanceTo(overlapB[j]->PointAtStart()) < 
intersection_tolerance_B) {
+               overlaps[i]->m_curve3d = link_curves(overlaps[i]->m_curve3d, 
overlaps[j]->m_curve3d);
+               overlaps[i]->m_curveA = link_curves(overlaps[i]->m_curveA, 
overlaps[j]->m_curveA);
+               overlaps[i]->m_curveB = link_curves(overlaps[i]->m_curveB, 
overlaps[j]->m_curveB);
+           } else if 
(overlaps[i]->m_curve3d->PointAtStart().DistanceTo(overlaps[j]->m_curve3d->PointAtStart())
 < intersection_tolerance
+                      && 
overlaps[i]->m_curveA->PointAtStart().DistanceTo(overlaps[j]->m_curveA->PointAtStart())
 < intersection_tolerance_A
+                      && 
overlaps[i]->m_curveB->PointAtStart().DistanceTo(overlaps[j]->m_curveB->PointAtStart())
 < intersection_tolerance_B) {
                // end -- start -- start -- end
-               if (overlaps[i]->Reverse() && overlapA[i]->Reverse() && 
overlapB[i]->Reverse()) {
-                   overlaps[i] = link_curves(overlaps[i], overlaps[j]);
-                   overlapA[i] = link_curves(overlapA[i], overlapA[j]);
-                   overlapB[i] = link_curves(overlapB[i], overlapB[j]);
+               if (overlaps[i]->m_curve3d->Reverse() && 
overlaps[i]->m_curveA->Reverse() && overlaps[i]->m_curveB->Reverse()) {
+                   overlaps[i]->m_curve3d = 
link_curves(overlaps[i]->m_curve3d, overlaps[j]->m_curve3d);
+                   overlaps[i]->m_curveA = link_curves(overlaps[i]->m_curveA, 
overlaps[j]->m_curveA);
+                   overlaps[i]->m_curveB = link_curves(overlaps[i]->m_curveB, 
overlaps[j]->m_curveB);
                }
-           } else if 
(overlaps[i]->PointAtEnd().DistanceTo(overlaps[j]->PointAtEnd()) < 
intersection_tolerance
-                      && 
overlapA[i]->PointAtEnd().DistanceTo(overlapA[j]->PointAtEnd()) < 
intersection_tolerance_A
-                      && 
overlapB[i]->PointAtEnd().DistanceTo(overlapB[j]->PointAtEnd()) < 
intersection_tolerance_B) {
+           } else if 
(overlaps[i]->m_curve3d->PointAtEnd().DistanceTo(overlaps[j]->m_curve3d->PointAtEnd())
 < intersection_tolerance
+                      && 
overlaps[i]->m_curveA->PointAtEnd().DistanceTo(overlaps[j]->m_curveA->PointAtEnd())
 < intersection_tolerance_A
+                      && 
overlaps[i]->m_curveB->PointAtEnd().DistanceTo(overlaps[j]->m_curveB->PointAtEnd())
 < intersection_tolerance_B) {
                // start -- end -- end -- start
-               if (overlaps[j]->Reverse() && overlapA[j]->Reverse() && 
overlapB[j]->Reverse()) {
-                   overlaps[i] = link_curves(overlaps[i], overlaps[j]);
-                   overlapA[i] = link_curves(overlapA[i], overlapA[j]);
-                   overlapB[i] = link_curves(overlapB[i], overlapB[j]);
+               if (overlaps[j]->m_curve3d->Reverse() && 
overlaps[j]->m_curveA->Reverse() && overlaps[j]->m_curveB->Reverse()) {
+                   overlaps[i]->m_curve3d = 
link_curves(overlaps[i]->m_curve3d, overlaps[j]->m_curve3d);
+                   overlaps[i]->m_curveA = link_curves(overlaps[i]->m_curveA, 
overlaps[j]->m_curveA);
+                   overlaps[i]->m_curveB = link_curves(overlaps[i]->m_curveB, 
overlaps[j]->m_curveB);
                }
            }
        }

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