Revision: 57090
http://sourceforge.net/p/brlcad/code/57090
Author: phoenixyjll
Date: 2013-08-23 04:35:25 +0000 (Fri, 23 Aug 2013)
Log Message:
-----------
Tweak the implementation of LinkedCurve - we should keep the original curve
segment so that we can then share an edge with a neighboring face.
Modified Paths:
--------------
brlcad/trunk/src/libbrep/boolean.cpp
Modified: brlcad/trunk/src/libbrep/boolean.cpp
===================================================================
--- brlcad/trunk/src/libbrep/boolean.cpp 2013-08-23 04:25:03 UTC (rev
57089)
+++ brlcad/trunk/src/libbrep/boolean.cpp 2013-08-23 04:35:25 UTC (rev
57090)
@@ -64,6 +64,11 @@
int m_fi1; // index of the first face
int m_fi2; // index of the second face
int m_ci; // index in the events array
+ // Default constructor. Set all to an invalid value.
+ SSICurveInfo()
+ {
+ m_fi1 = m_fi2 = m_ci = -1;
+ }
};
#endif
@@ -73,15 +78,156 @@
#if USE_CONNECTIVITY_GRAPH
SSICurveInfo m_info;
#endif
+
+ SSICurve()
+ {
+ m_curve = NULL;
+ }
+
+ SSICurve(ON_Curve* curve)
+ {
+ m_curve = curve;
+ }
+
+ SSICurve *Duplicate() const
+ {
+ SSICurve *out = new SSICurve();
+ if (out != NULL) {
+ *out = *this;
+ out->m_curve = m_curve->Duplicate();
+ }
+ return out;
+ }
};
+void AppendToPolyCurve(ON_Curve* curve, ON_PolyCurve& polycurve);
struct LinkedCurve {
+private:
ON_Curve* m_curve;
+public:
+ ON_SimpleArray<SSICurve> m_ssi_curves;
+
+ // Default constructor
+ LinkedCurve()
+ {
+ m_curve = NULL;
+ }
+
+ ~LinkedCurve()
+ {
+ m_curve = NULL;
+ }
+
+ ON_3dPoint PointAtStart() const
+ {
+ if (m_ssi_curves.Count())
+ return m_ssi_curves[0].m_curve->PointAtStart();
+ else
+ return ON_3dPoint::UnsetPoint;
+ }
+
+ ON_3dPoint PointAtEnd() const
+ {
+ if (m_ssi_curves.Count())
+ return m_ssi_curves.Last()->m_curve->PointAtEnd();
+ else
+ return ON_3dPoint::UnsetPoint;
+ }
+
+ bool IsClosed() const
+ {
+ if (m_ssi_curves.Count() == 0)
+ return false;
+ return PointAtStart().DistanceTo(PointAtEnd()) < ON_ZERO_TOLERANCE;
+ }
+
+ bool IsValid() const
+ {
+ for (int i = 1; i < m_ssi_curves.Count(); i++) {
+ if
(m_ssi_curves[i].m_curve->PointAtStart().DistanceTo(m_ssi_curves[i-1].m_curve->PointAtEnd())
>= ON_ZERO_TOLERANCE) {
+ bu_log("The LinkedCurve is not valid.\n");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool Reverse()
+ {
+ ON_SimpleArray<SSICurve> newarray;
+ for (int i = m_ssi_curves.Count() - 1; i >= 0; i--) {
+ if (!m_ssi_curves[i].m_curve->Reverse())
+ return false;
+ newarray.Append(m_ssi_curves[i]);
+ }
+ m_ssi_curves = newarray;
+ return true;
+ }
+
+ void Append(const LinkedCurve& lc)
+ {
+ m_ssi_curves.Append(lc.m_ssi_curves.Count(), lc.m_ssi_curves.Array());
+ }
+
+ void Append(const SSICurve& sc)
+ {
+ m_ssi_curves.Append(sc);
+ }
+
+ void AppendCurvesToArray(ON_SimpleArray<ON_Curve*>& arr) const
+ {
+ for (int i = 0; i < m_ssi_curves.Count(); i++)
+ arr.Append(m_ssi_curves[i].m_curve);
+ }
+
#if USE_CONNECTIVITY_GRAPH
- ON_SimpleArray<SSICurveInfo> m_info_array;
+ void AppendSSIInfoToArray(ON_SimpleArray<SSICurveInfo>& arr) const
+ {
+ for (int i = 0; i < m_ssi_curves.Count(); i++)
+ arr.Append(m_ssi_curves[i].m_info);
+ }
#endif
+
+ const ON_Curve* Curve()
+ {
+ if (m_curve != NULL)
+ return m_curve;
+ if (m_ssi_curves.Count() == 0 || !IsValid())
+ return NULL;
+ ON_PolyCurve* polycurve = new ON_PolyCurve;
+ for (int i = 0; i < m_ssi_curves.Count(); i++)
+ AppendToPolyCurve(m_ssi_curves[i].m_curve, *polycurve);
+ m_curve = polycurve;
+ return m_curve;
+ }
+
+ ON_3dPoint PointAt(double t)
+ {
+ const ON_Curve* c = Curve();
+ if (c == NULL)
+ return ON_3dPoint::UnsetPoint;
+ return c->PointAt(t);
+ }
+
+ const ON_Interval Domain()
+ {
+ const ON_Curve* c = Curve();
+ if (c == NULL)
+ return ON_Interval::EmptyInterval;
+ return c->Domain();
+ }
+
+ ON_Curve* SubCurve(double t1, double t2)
+ {
+ const ON_Curve* c = Curve();
+ if (c == NULL)
+ return NULL;
+ ON_Curve* dup = c->Duplicate();
+ return sub_curve(dup, t1, t2);
+ }
};
+
struct TrimmedFace {
@@ -379,77 +525,67 @@
ON_ClassArray<LinkedCurve> tmp;
for (int i = 0; i < in.Count(); i++) {
LinkedCurve linked;
- linked.m_curve = in[i].m_curve->Duplicate();
-#if USE_CONNECTIVITY_GRAPH
- linked.m_info_array.Append(in[i].m_info);
-#endif
+ linked.m_ssi_curves.Append(*in[i].Duplicate());
tmp.Append(linked);
}
// As usual, we use a greedy approach.
for (int i = 0; i < tmp.Count(); i++) {
for (int j = 0; j < tmp.Count(); j++) {
- if (tmp[i].m_curve == NULL || tmp[i].m_curve->IsClosed())
+ if (tmp[i].m_ssi_curves.Count() == 0 || tmp[i].IsClosed())
break;
- if (tmp[j].m_curve == NULL || tmp[j].m_curve->IsClosed() || j == i)
+ if (tmp[j].m_ssi_curves.Count() == 0 || tmp[j].IsClosed() || j == i)
continue;
- ON_Curve *c1 = NULL, *c2 = NULL;
+ LinkedCurve *c1 = NULL, *c2 = NULL;
double dis;
// Link curves that share an end point.
- if ((dis =
tmp[i].m_curve->PointAtStart().DistanceTo(tmp[j].m_curve->PointAtEnd())) <
INTERSECTION_TOL) {
+ if ((dis = tmp[i].PointAtStart().DistanceTo(tmp[j].PointAtEnd())) <
INTERSECTION_TOL) {
// end -- start -- end -- start
- c1 = tmp[j].m_curve;
- c2 = tmp[i].m_curve;
- } else if ((dis =
tmp[i].m_curve->PointAtEnd().DistanceTo(tmp[j].m_curve->PointAtStart())) <
INTERSECTION_TOL) {
+ c1 = &tmp[j];
+ c2 = &tmp[i];
+ } else if ((dis =
tmp[i].PointAtEnd().DistanceTo(tmp[j].PointAtStart())) < INTERSECTION_TOL) {
// start -- end -- start -- end
- c1 = tmp[i].m_curve;
- c2 = tmp[j].m_curve;
- } else if ((dis =
tmp[i].m_curve->PointAtStart().DistanceTo(tmp[j].m_curve->PointAtStart())) <
INTERSECTION_TOL) {
+ c1 = &tmp[i];
+ c2 = &tmp[j];
+ } else if ((dis =
tmp[i].PointAtStart().DistanceTo(tmp[j].PointAtStart())) < INTERSECTION_TOL) {
// end -- start -- start -- end
- if (tmp[i].m_curve->Reverse()) {
- c1 = tmp[i].m_curve;
- c2 = tmp[j].m_curve;
+ if (tmp[i].Reverse()) {
+ c1 = &tmp[i];
+ c2 = &tmp[j];
}
- } else if ((dis =
tmp[i].m_curve->PointAtEnd().DistanceTo(tmp[j].m_curve->PointAtEnd())) <
INTERSECTION_TOL) {
+ } else if ((dis =
tmp[i].PointAtEnd().DistanceTo(tmp[j].PointAtEnd())) < INTERSECTION_TOL) {
// start -- end -- end -- start
- if (tmp[j].m_curve->Reverse()) {
- c1 = tmp[i].m_curve;
- c2 = tmp[j].m_curve;
+ if (tmp[j].Reverse()) {
+ c1 = &tmp[i];
+ c2 = &tmp[j];
}
} else
continue;
if (c1 != NULL && c2 != NULL) {
ON_PolyCurve* polycurve = new ON_PolyCurve;
- AppendToPolyCurve(c1, *polycurve);
+ LinkedCurve newcurve;
+ newcurve.Append(*c1);
if (dis > ON_ZERO_TOLERANCE)
- AppendToPolyCurve(new ON_LineCurve(c1->PointAtEnd(),
c2->PointAtStart()), *polycurve);
- AppendToPolyCurve(c2, *polycurve);
- tmp[i].m_curve = polycurve;
- tmp[j].m_curve = NULL;
-#if USE_CONNECTIVITY_GRAPH
- tmp[i].m_info_array.Append(tmp[j].m_info_array.Count(),
tmp[j].m_info_array.Array());
-#endif
+ newcurve.Append(SSICurve(new ON_LineCurve(c1->PointAtEnd(),
c2->PointAtStart())));
+ newcurve.Append(*c2);
+ tmp[i] = newcurve;
+ tmp[j].m_ssi_curves.Empty();
}
// Check whether tmp[i] is closed within a tolerance
- if
(tmp[i].m_curve->PointAtStart().DistanceTo(tmp[i].m_curve->PointAtEnd()) <
INTERSECTION_TOL && !tmp[i].m_curve->IsClosed()) {
+ if (tmp[i].PointAtStart().DistanceTo(tmp[i].PointAtEnd()) <
INTERSECTION_TOL && !tmp[i].IsClosed()) {
// make IsClosed() true
- c1 = tmp[i].m_curve;
- c2 = new ON_LineCurve(tmp[i].m_curve->PointAtEnd(),
tmp[i].m_curve->PointAtStart());
- ON_PolyCurve* polycurve = new ON_PolyCurve;
- AppendToPolyCurve(c1, *polycurve);
- AppendToPolyCurve(c2, *polycurve);
- tmp[i].m_curve = polycurve;
+ tmp[i].Append(SSICurve(new ON_LineCurve(tmp[i].PointAtEnd(),
tmp[i].PointAtStart())));
}
}
}
// Append the remaining curves to out.
for (int i = 0; i < tmp.Count(); i++)
- if (tmp[i].m_curve != NULL)
+ if (tmp[i].m_ssi_curves.Count() != 0)
out.Append(tmp[i]);
if (DEBUG_BREP_BOOLEAN)
@@ -458,7 +594,7 @@
HIDDEN int
-split_trimmed_face(ON_SimpleArray<TrimmedFace*> &out, const TrimmedFace *in,
const ON_ClassArray<LinkedCurve> &curves)
+split_trimmed_face(ON_SimpleArray<TrimmedFace*> &out, const TrimmedFace *in,
ON_ClassArray<LinkedCurve> &curves)
{
/* We followed the algorithms described in:
* S. Krishnan, A. Narkhede, and D. Manocha. BOOLE: A System to Compute
@@ -483,7 +619,7 @@
for (int i = 0; i < in->m_outerloop.Count(); i++) {
for (int j = 0; j < curves.Count(); j++) {
ON_SimpleArray<ON_X_EVENT> x_event;
- ON_Intersect(in->m_outerloop[i], curves[j].m_curve, x_event,
INTERSECTION_TOL);
+ ON_Intersect(in->m_outerloop[i], curves[j].Curve(), x_event,
INTERSECTION_TOL);
for (int k = 0; k < x_event.Count(); k++) {
IntersectPoint tmp_pt;
tmp_pt.m_pt = x_event[k].m_A[0];
@@ -500,9 +636,9 @@
tmp_pt.m_t_for_rank = x_event[k].m_b[1];
intersect.Append(tmp_pt);
}
+ if (x_event.Count())
+ have_intersect[j] = true;
}
- if (x_event.Count())
- have_intersect[j] = true;
}
}
@@ -520,19 +656,19 @@
if (!have_intersect[i]) {
// The start point cannot be on the boundary of the loop, because
// there is no intersections between curves[i] and the loop.
- if (IsPointInsideLoop(curves[i].m_curve->PointAtStart(),
in->m_outerloop)) {
- if (curves[i].m_curve->IsClosed()) {
+ if (IsPointInsideLoop(curves[i].PointAtStart(), in->m_outerloop)) {
+ if (curves[i].IsClosed()) {
ON_SimpleArray<ON_Curve*> iloop;
- iloop.Append(curves[i].m_curve);
+ curves[i].AppendCurvesToArray(iloop);
innerloops.push_back(iloop);
TrimmedFace *newface = new TrimmedFace();
newface->m_face = in->m_face;
- newface->m_outerloop.Append(curves[i].m_curve);
+ curves[i].AppendCurvesToArray(newface->m_outerloop);
#if USE_CONNECTIVITY_GRAPH
// It doesn't share its parent's outerloop
newface->m_parts.Empty();
// It used the SSI curve (curves[i])
- newface->m_ssi_info.Append(curves[i].m_info_array.Count(),
curves[i].m_info_array.Array());
+ curves[i].AppendSSIInfoToArray(newface->m_ssi_info);
curves_from_ssi.Append(curves[i]);
#endif
out.Append(newface);
@@ -563,10 +699,10 @@
if (pts_on_curves[i]->Count() < 2)
ipt->m_in_out = IntersectPoint::UNSET;
else {
- ON_3dPoint left = j == 0 ? curves[i].m_curve->PointAtStart() :
-
curves[i].m_curve->PointAt((ipt->m_t_for_rank+(*pts_on_curves[i])[j-1]->m_t_for_rank)*0.5);
- ON_3dPoint right = j == pts_on_curves[i]->Count() - 1 ?
curves[i].m_curve->PointAtEnd() :
-
curves[i].m_curve->PointAt((ipt->m_t_for_rank+(*pts_on_curves[i])[j+1]->m_t_for_rank)*0.5);
+ ON_3dPoint left = j == 0 ? curves[i].PointAtStart() :
+
curves[i].PointAt((ipt->m_t_for_rank+(*pts_on_curves[i])[j-1]->m_t_for_rank)*0.5);
+ ON_3dPoint right = j == pts_on_curves[i]->Count() - 1 ?
curves[i].PointAtEnd() :
+
curves[i].PointAt((ipt->m_t_for_rank+(*pts_on_curves[i])[j+1]->m_t_for_rank)*0.5);
// If the point is on the boundary, we treat it with the same
// way as it's outside.
// For example, the left side is inside, and the right's on
@@ -580,9 +716,9 @@
ipt->m_in_out = IntersectPoint::UNSET;
continue;
}
- if (j == 0 && ON_NearZero(ipt->m_t_for_rank -
curves[i].m_curve->Domain().Min())) {
+ if (j == 0 && ON_NearZero(ipt->m_t_for_rank -
curves[i].Domain().Min())) {
ipt->m_in_out = right_in ? IntersectPoint::IN :
IntersectPoint::OUT;
- } else if (j == pts_on_curves[i]->Count() - 1 &&
ON_NearZero(ipt->m_t_for_rank - curves[i].m_curve->Domain().Max())) {
+ } else if (j == pts_on_curves[i]->Count() - 1 &&
ON_NearZero(ipt->m_t_for_rank - curves[i].Domain().Max())) {
ipt->m_in_out = left_in ? IntersectPoint::OUT :
IntersectPoint::IN;
} else {
if (left_in && right_in) {
@@ -776,7 +912,7 @@
std::swap(t1, t2);
need_reverse = false;
}
- ON_Curve* seg_on_SSI = sub_curve(curves[p.m_type].m_curve, t1, t2);
+ ON_Curve* seg_on_SSI = curves[p.m_type].SubCurve(t1, t2);
if (seg_on_SSI == NULL) {
bu_log("sub_curve() failed.\n");
continue;
@@ -831,7 +967,7 @@
for (int j = 0; j < newloop_start_end.Count(); j++)
if (newloop_start_end[j].first.m_seg != -1)
newface->m_parts.Append(newloop_start_end[j]);
- newface->m_ssi_info.Append(curves[p.m_type].m_info_array.Count(),
curves[p.m_type].m_info_array.Array());
+ curves[p.m_type].AppendSSIInfoToArray(newface->m_ssi_info);
#endif
out.Append(newface);
}
@@ -876,7 +1012,7 @@
if (outerloop_start_end[i].first.m_seg != -1)
newface->m_parts.Append(outerloop_start_end[i]);
for (int i = 0; i < curves_from_ssi.Count(); i++)
-
newface->m_ssi_info.Append(curves_from_ssi[i].m_info_array.Count(),
curves_from_ssi[i].m_info_array.Array());
+ curves_from_ssi[i].AppendSSIInfoToArray(newface->m_ssi_info);
#endif
out.Append(newface);
}
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