Revision: 57017
http://sourceforge.net/p/brlcad/code/57017
Author: phoenixyjll
Date: 2013-08-21 10:07:35 +0000 (Wed, 21 Aug 2013)
Log Message:
-----------
Don't use start, end to represent which part of the outerloop it occupies,
which can only represent a single interval. Use array of intervals instead.
Modified Paths:
--------------
brlcad/trunk/src/libbrep/boolean.cpp
Modified: brlcad/trunk/src/libbrep/boolean.cpp
===================================================================
--- brlcad/trunk/src/libbrep/boolean.cpp 2013-08-21 05:06:22 UTC (rev
57016)
+++ brlcad/trunk/src/libbrep/boolean.cpp 2013-08-21 10:07:35 UTC (rev
57017)
@@ -66,7 +66,9 @@
#if USE_CONNECTIVITY_GRAPH
// Connectivity graph support
ON_SimpleArray<TrimmedFace*> neighbors;
- IntersectPoint start, end;
+ // which parts of its parent's outerloop are used, decribed in multiple
+ // pairs of IntersectPoints (multiple intervals)
+ ON_ClassArray<std::pair<IntersectPoint, IntersectPoint> > parts;
#endif
TrimmedFace *Duplicate() const
{
@@ -75,8 +77,7 @@
out->outerloop = outerloop;
out->innerloop = innerloop;
#if USE_CONNECTIVITY_GRAPH
- out->start = start;
- out->end = end;
+ out->parts = parts;
// Don't copy the neighbors
#endif
return out;
@@ -483,7 +484,8 @@
newface->face = in->face;
newface->outerloop.Append(curves[i]);
#if USE_CONNECTIVITY_GRAPH
- newface->start.m_seg = newface->start.m_t =
newface->end.m_seg = newface->end.m_t = ON_UNSET_VALUE;
+ // It doesn't share its parent's outerloop
+ newface->parts.Empty();
#endif
out.Append(newface);
}
@@ -565,7 +567,13 @@
intersect.QuickSort(compare_t);
// Split the outer loop.
- ON_SimpleArray<ON_Curve*> outerloop;
+ ON_SimpleArray<ON_Curve*> outerloop; // segments of the outerloop
+#if USE_CONNECTIVITY_GRAPH
+ // the start point and end point of an outerloop segment
+ // outerloop_start_end[] and outerloop[] should have the same size, and
+ // outerloop_start_end[i] should be corresponding to outerloop[i] exactly.
+ ON_SimpleArray<std::pair<IntersectPoint, IntersectPoint> >
outerloop_start_end;
+#endif
int isect_iter = 0;
for (int i = 0; i < in->outerloop.Count(); i++) {
ON_Curve *curve_on_loop = in->outerloop[i]->Duplicate();
@@ -588,9 +596,21 @@
split_called = true;
}
}
- if (left != NULL)
+ if (left != NULL) {
outerloop.Append(left);
- else if (split_called) {
+#if USE_CONNECTIVITY_GRAPH
+ IntersectPoint start;
+ if (outerloop_start_end.Count() == 0 ||
outerloop_start_end.Last()->second.m_seg != i) {
+ // It should use the start point of in->outerloop[i]
+ start.m_seg = i;
+ start.m_t = in->outerloop[i]->Domain().Min();
+ } else {
+ // Continuous to the last one
+ start = outerloop_start_end.Last()->second;
+ }
+ outerloop_start_end.Append(std::make_pair(start, isect_pt));
+#endif
+ } else if (split_called) {
bu_log("Split failed.\n");
if (curve_on_loop) {
bu_log("Domain: [%lf, %lf]\n",
curve_on_loop->Domain().Min(), curve_on_loop->Domain().Max());
@@ -599,8 +619,23 @@
}
intersect[isect_iter].m_pos = outerloop.Count() - 1;
}
- if (curve_on_loop)
+ if (curve_on_loop) {
outerloop.Append(curve_on_loop);
+#if USE_CONNECTIVITY_GRAPH
+ IntersectPoint start, end;
+ if (outerloop_start_end.Count() == 0 ||
outerloop_start_end.Last()->second.m_seg != i) {
+ // It should use the start point of in->outerloop[i]
+ start.m_seg = i;
+ start.m_t = in->outerloop[i]->Domain().Min();
+ } else {
+ // Continuous to the last one
+ start = outerloop_start_end.Last()->second;
+ }
+ end.m_seg = i;
+ end.m_t = in->outerloop[i]->Domain().Max();
+ outerloop_start_end.Append(std::make_pair(start, end));
+#endif
+ }
}
// Append the first element at the last to handle some special cases.
@@ -616,6 +651,9 @@
bu_log("ON_Curve::Duplicate() failed.\n");
outerloop.Append(outerloop[i]);
}
+#if USE_CONNECTIVITY_GRAPH
+ outerloop_start_end.Append(outerloop_start_end[i]);
+#endif
}
intersect.Last()->m_pos = outerloop.Count() - 1;
}
@@ -623,6 +661,14 @@
std::stack<int> s;
for (int i = 0; i < intersect.Count(); i++) {
+#if USE_CONNECTIVITY_GRAPH
+ // Check the validity of outerloop_start_end
+ if (outerloop_start_end.Count() != outerloop.Count()) {
+ bu_log("split_trimmed_face() Error [i = %d]:
outerloop_start_end.Count() != outerloop.Count()\n", i);
+ return -1;
+ }
+#endif
+
// Ignore UNSET IntersectPoints.
if (intersect[i].m_in_out == IntersectPoint::UNSET)
continue;
@@ -657,9 +703,15 @@
// need to form a new loop
ON_SimpleArray<ON_Curve*> newloop;
+#if USE_CONNECTIVITY_GRAPH
+ ON_SimpleArray<std::pair<IntersectPoint, IntersectPoint> >
newloop_start_end;
+#endif
int curve_count = q.m_pos - p.m_pos;
for (int j = p.m_pos + 1; j <= q.m_pos; j++) {
newloop.Append(outerloop[j]);
+#if USE_CONNECTIVITY_GRAPH
+ newloop_start_end.Append(outerloop_start_end[j]);
+#endif
}
if (p.m_type != q.m_type) {
@@ -701,6 +753,18 @@
outerloop[outerloop.Count()-1] = NULL;
outerloop.Remove();
}
+#if USE_CONNECTIVITY_GRAPH
+ // Update outerloop_start_end
+ IntersectPoint invalid_point;
+ invalid_point.m_seg = -1;
+ outerloop_start_end[p.m_pos + 1] = std::make_pair(invalid_point,
invalid_point);
+ k = p.m_pos + 2;
+ for (int j = q.m_pos + 1; j < outerloop_start_end.Count(); j++)
+ outerloop_start_end[k++] = outerloop_start_end[j];
+ while (k < outerloop_start_end.Count()) {
+ outerloop_start_end.Remove();
+ }
+#endif
// Update m_pos
for (int j = i + 1; j < intersect.Count(); j++)
intersect[j].m_pos -= curve_count - 1;
@@ -713,8 +777,9 @@
newface->face = in->face;
newface->outerloop.Append(newloop.Count(), newloop.Array());
#if USE_CONNECTIVITY_GRAPH
- newface->start = p;
- newface->end = q;
+ for (int i = 0; i < newloop_start_end.Count(); i++)
+ if (newloop_start_end[i].first.m_seg != -1)
+ newface->parts.Append(newloop_start_end[i]);
#endif
out.Append(newface);
}
@@ -722,8 +787,12 @@
// Remove the duplicated segments before the first intersection point.
if (intersect.Count()) {
- for (int i = 0; i <= intersect[0].m_pos; i++)
+ for (int i = 0; i <= intersect[0].m_pos; i++) {
outerloop.Remove(0);
+#if USE_CONNECTIVITY_GRAPH
+ outerloop_start_end.Remove(0);
+#endif
+ }
}
if (out.Count() == 0) {
@@ -737,14 +806,23 @@
newface->innerloop = in->innerloop;
newface->innerloop.insert(newface->innerloop.end(),
innerloops.begin(), innerloops.end());
#if USE_CONNECTIVITY_GRAPH
- if (intersect.Count()) {
- // XXX: Use more than one intervals
- newface->start = intersect[0];
- newface->end = *intersect.Last();
+ /* if (intersect.Count()) {
+ // Eliminate the parts of outerloop used by other sub-faces
+ for (int i = 0; i < out.Count(); i++) {
+ if (out[i]->parts.Count() == 0)
+ continue;
+ IntersectPoint& start = intersect[0];
+ for (int j = 0; j < out[i]->parts.Count(); j++) {
+ newface->parts.Append(std::make_pair(start,
out[i]->parts[j].first));
+ start = out[i]->parts[j].second;
+ }
+ }
} else {
- newface->start = in->start;
- newface->end = in->end;
- }
+ newface->parts = in->parts;
+ } */
+ for (int i = 0; i < outerloop_start_end.Count(); i++)
+ if (outerloop_start_end[i].first.m_seg != -1)
+ newface->parts.Append(outerloop_start_end[i]);
#endif
out.Append(newface);
}
@@ -982,10 +1060,14 @@
first->innerloop.push_back(iloop);
}
#if USE_CONNECTIVITY_GRAPH
- first->start.m_seg = 0;
- first->start.m_t = first->outerloop.Count() ?
first->outerloop[0]->Domain().Min() : ON_UNSET_VALUE;
- first->end.m_seg = first->outerloop.Count() - 1;
- first->end.m_t = first->outerloop.Count() ?
(*first->outerloop.Last())->Domain().Max() : ON_UNSET_VALUE;
+ if (first->outerloop.Count()) {
+ IntersectPoint start, end;
+ start.m_seg = 0;
+ start.m_t = first->outerloop[0]->Domain().Min();
+ end.m_seg = first->outerloop.Count() - 1;
+ end.m_t = (*first->outerloop.Last())->Domain().Max();
+ first->parts.Append(std::make_pair(start, end));
+ }
#endif
original_faces.Append(first);
}
@@ -1040,25 +1122,40 @@
for (int i = 0; i < original_faces.Count(); i++) {
for (int j = 0; j < trimmedfaces[i].Count(); j++) {
TrimmedFace* t_face = trimmedfaces[i][j];
- if (t_face->start.m_seg == -1 || t_face->start.m_t ==
ON_UNSET_VALUE || t_face->end.m_seg == -1 || t_face->end.m_t == ON_UNSET_VALUE)
+ if (t_face->parts.Count() == 0)
continue;
for (int k = 0; k < original_faces[i]->neighbors.Count(); k++) {
int neighbor_index =
original_faces.Search(original_faces[i]->neighbors[k]);
if (neighbor_index == -1)
continue;
for (int l = 0; l < trimmedfaces[neighbor_index].Count(); l++) {
+ // Search all of its parent's neighbors' children, and check
+ // whether they share a common part of the original
outerloop.
+ // If their "parts" intersect (overlap) in some way, they
are
+ // neighbors again. (Neighboring parents' children become
new
+ // neighbors: parent[i]'s child[j] with parent[i]'s
neighbor[k]'s
+ // child[l])
TrimmedFace* another_face = trimmedfaces[neighbor_index][l];
- if (another_face->start.m_seg == -1 ||
another_face->start.m_t == ON_UNSET_VALUE
- || another_face->end.m_seg == -1 ||
another_face->end.m_t == ON_UNSET_VALUE)
+ if (another_face->parts.Count() == 0)
continue;
- const IntersectPoint& start = compare_t(&(t_face->start),
&(another_face->start)) < 0 ? another_face->start : t_face->start;
- const IntersectPoint& end = compare_t(&(t_face->end),
&(another_face->end)) < 0 ? t_face->end : another_face->end;
- if (compare_t(&start, &end) < 0) {
- // The intervals intersect
- if (t_face->neighbors.Search(another_face) == -1)
- t_face->neighbors.Append(another_face);
- if (another_face->neighbors.Search(t_face) == -1)
- another_face->neighbors.Append(t_face);
+ // Find an intersection between all their "parts".
+ for (int i1 = 0; i1 < t_face->parts.Count(); i1++) {
+ for (int i2 = 0; i2 < another_face->parts.Count();
i2++) {
+ const IntersectPoint& start1 =
t_face->parts[i1].first;
+ const IntersectPoint& start2 =
another_face->parts[i2].first;
+ const IntersectPoint& end1 =
t_face->parts[i1].second;
+ const IntersectPoint& end2 =
another_face->parts[i2].second;
+ const IntersectPoint& start_max =
compare_t(&start1, &start2) < 0 ? start2 : start1;
+ const IntersectPoint& end_min = compare_t(&end1,
&end2) < 0 ? end1 : end2;
+ if (compare_t(&start_max, &end_min) < 0) {
+ // The intervals intersect
+ if (t_face->neighbors.Search(another_face) ==
-1)
+ t_face->neighbors.Append(another_face);
+ if (another_face->neighbors.Search(t_face) ==
-1)
+ another_face->neighbors.Append(t_face);
+ break;
+ }
+ }
}
}
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Introducing Performance Central, a new site from SourceForge and
AppDynamics. Performance Central is your source for news, insights,
analysis and resources for efficient Application Performance Management.
Visit us today!
http://pubads.g.doubleclick.net/gampad/clk?id=48897511&iu=/4140/ostg.clktrk
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits