Revision: 57057
http://sourceforge.net/p/brlcad/code/57057
Author: phoenixyjll
Date: 2013-08-22 09:00:37 +0000 (Thu, 22 Aug 2013)
Log Message:
-----------
Keep the information of the usage of SSI curve, so that we can know the
connection between two trimmed faces (split from two surfaces), and get the
connectivity graph of the new geometry after boolean evaluation.
Modified Paths:
--------------
brlcad/trunk/src/libbrep/boolean.cpp
Modified: brlcad/trunk/src/libbrep/boolean.cpp
===================================================================
--- brlcad/trunk/src/libbrep/boolean.cpp 2013-08-22 04:27:20 UTC (rev
57056)
+++ brlcad/trunk/src/libbrep/boolean.cpp 2013-08-22 09:00:37 UTC (rev
57057)
@@ -59,6 +59,31 @@
};
+#if USE_CONNECTIVITY_GRAPH
+struct SSICurveInfo {
+ int m_fi1; // index of the first face
+ int m_fi2; // index of the second face
+ int m_ci; // index in the events array
+};
+#endif
+
+
+struct SSICurve {
+ ON_Curve* m_curve;
+#if USE_CONNECTIVITY_GRAPH
+ SSICurveInfo m_info;
+#endif
+};
+
+
+struct LinkedCurve {
+ ON_Curve* m_curve;
+#if USE_CONNECTIVITY_GRAPH
+ ON_SimpleArray<SSICurveInfo> m_info_array;
+#endif
+};
+
+
struct TrimmedFace {
ON_SimpleArray<ON_Curve*> m_outerloop;
std::vector<ON_SimpleArray<ON_Curve*> > m_innerloop;
@@ -69,6 +94,8 @@
// which parts of its parent's outerloop are used, decribed in multiple
// pairs of IntersectPoints (multiple intervals)
ON_ClassArray<std::pair<IntersectPoint, IntersectPoint> > m_parts;
+ // which SSI curves are used.
+ ON_SimpleArray<SSICurveInfo> m_ssi_info;
#endif
TrimmedFace *Duplicate() const
{
@@ -78,6 +105,7 @@
out->m_innerloop = m_innerloop;
#if USE_CONNECTIVITY_GRAPH
out->m_parts = m_parts;
+ out->m_ssi_info = m_ssi_info;
// Don't copy the neighbors
#endif
return out;
@@ -342,48 +370,53 @@
HIDDEN void
-link_curves(const ON_SimpleArray<ON_Curve*>& in, ON_SimpleArray<ON_Curve*>&
out)
+link_curves(const ON_SimpleArray<SSICurve>& in, ON_ClassArray<LinkedCurve>&
out)
{
// There might be two reasons why we need to link these curves.
// 1) They are from intersections with two different surfaces.
// 2) They are not continuous in the other surface's UV domain.
- ON_SimpleArray<ON_Curve*> tmp;
+ ON_ClassArray<LinkedCurve> tmp;
for (int i = 0; i < in.Count(); i++) {
- tmp.Append(in[i]->Duplicate());
+ LinkedCurve linked;
+ linked.m_curve = in[i].m_curve->Duplicate();
+#if USE_CONNECTIVITY_GRAPH
+ linked.m_info_array.Append(in[i].m_info);
+#endif
+ 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] == NULL || tmp[i]->IsClosed())
+ if (tmp[i].m_curve == NULL || tmp[i].m_curve->IsClosed())
break;
- if (tmp[j] == NULL || tmp[j]->IsClosed() || j == i)
+ if (tmp[j].m_curve == NULL || tmp[j].m_curve->IsClosed() || j == i)
continue;
ON_Curve *c1 = NULL, *c2 = NULL;
double dis;
// Link curves that share an end point.
- if ((dis = tmp[i]->PointAtStart().DistanceTo(tmp[j]->PointAtEnd()))
< INTERSECTION_TOL) {
+ if ((dis =
tmp[i].m_curve->PointAtStart().DistanceTo(tmp[j].m_curve->PointAtEnd())) <
INTERSECTION_TOL) {
// end -- start -- end -- start
- c1 = tmp[j];
- c2 = tmp[i];
- } else if ((dis =
tmp[i]->PointAtEnd().DistanceTo(tmp[j]->PointAtStart())) < INTERSECTION_TOL) {
+ 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) {
// start -- end -- start -- end
- c1 = tmp[i];
- c2 = tmp[j];
- } else if ((dis =
tmp[i]->PointAtStart().DistanceTo(tmp[j]->PointAtStart())) < INTERSECTION_TOL) {
+ 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) {
// end -- start -- start -- end
- if (tmp[i]->Reverse()) {
- c1 = tmp[i];
- c2 = tmp[j];
+ if (tmp[i].m_curve->Reverse()) {
+ c1 = tmp[i].m_curve;
+ c2 = tmp[j].m_curve;
}
- } else if ((dis =
tmp[i]->PointAtEnd().DistanceTo(tmp[j]->PointAtEnd())) < INTERSECTION_TOL) {
+ } else if ((dis =
tmp[i].m_curve->PointAtEnd().DistanceTo(tmp[j].m_curve->PointAtEnd())) <
INTERSECTION_TOL) {
// start -- end -- end -- start
- if (tmp[j]->Reverse()) {
- c1 = tmp[i];
- c2 = tmp[j];
+ if (tmp[j].m_curve->Reverse()) {
+ c1 = tmp[i].m_curve;
+ c2 = tmp[j].m_curve;
}
} else
continue;
@@ -394,26 +427,29 @@
if (dis > ON_ZERO_TOLERANCE)
AppendToPolyCurve(new ON_LineCurve(c1->PointAtEnd(),
c2->PointAtStart()), *polycurve);
AppendToPolyCurve(c2, *polycurve);
- tmp[i] = polycurve;
- tmp[j] = NULL;
+ 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
}
// Check whether tmp[i] is closed within a tolerance
- if (tmp[i]->PointAtStart().DistanceTo(tmp[i]->PointAtEnd()) <
INTERSECTION_TOL && !tmp[i]->IsClosed()) {
+ if
(tmp[i].m_curve->PointAtStart().DistanceTo(tmp[i].m_curve->PointAtEnd()) <
INTERSECTION_TOL && !tmp[i].m_curve->IsClosed()) {
// make IsClosed() true
- c1 = tmp[i];
- c2 = new ON_LineCurve(tmp[i]->PointAtEnd(),
tmp[i]->PointAtStart());
+ 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] = polycurve;
+ tmp[i].m_curve = polycurve;
}
}
}
// Append the remaining curves to out.
for (int i = 0; i < tmp.Count(); i++)
- if (tmp[i] != NULL)
+ if (tmp[i].m_curve != NULL)
out.Append(tmp[i]);
if (DEBUG_BREP_BOOLEAN)
@@ -422,7 +458,7 @@
HIDDEN int
-split_trimmed_face(ON_SimpleArray<TrimmedFace*> &out, const TrimmedFace *in,
const ON_SimpleArray<ON_Curve*> &curves)
+split_trimmed_face(ON_SimpleArray<TrimmedFace*> &out, const TrimmedFace *in,
const ON_ClassArray<LinkedCurve> &curves)
{
/* We followed the algorithms described in:
* S. Krishnan, A. Narkhede, and D. Manocha. BOOLE: A System to Compute
@@ -438,6 +474,7 @@
return 0;
}
+ // Get the intersection points between the SSI curves and the outerloop.
ON_SimpleArray<IntersectPoint> intersect;
ON_SimpleArray<bool> have_intersect(curves.Count());
for (int i = 0; i < curves.Count(); i++)
@@ -446,7 +483,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], x_event,
INTERSECTION_TOL);
+ ON_Intersect(in->m_outerloop[i], curves[j].m_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];
@@ -469,23 +506,34 @@
}
}
+#if USE_CONNECTIVITY_GRAPH
+ // Keep track of information about which SSI curves are used into the final
+ // trimmed face, so that we can know which trimmed face on the other face
+ // shares an SSI curve with it (and they become neighbors in the
connectivity
+ // graph).
+ ON_ClassArray<LinkedCurve> curves_from_ssi;
+#endif
+
// deal with the situations where there is no intersection
std::vector<ON_SimpleArray<ON_Curve*> > innerloops;
for (int i = 0; i < curves.Count(); i++) {
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]->PointAtStart(), in->m_outerloop)) {
- if (curves[i]->IsClosed()) {
+ if (IsPointInsideLoop(curves[i].m_curve->PointAtStart(),
in->m_outerloop)) {
+ if (curves[i].m_curve->IsClosed()) {
ON_SimpleArray<ON_Curve*> iloop;
- iloop.Append(curves[i]);
+ iloop.Append(curves[i].m_curve);
innerloops.push_back(iloop);
TrimmedFace *newface = new TrimmedFace();
newface->m_face = in->m_face;
- newface->m_outerloop.Append(curves[i]);
+ newface->m_outerloop.Append(curves[i].m_curve);
#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_from_ssi.Append(curves[i]);
#endif
out.Append(newface);
}
@@ -507,17 +555,18 @@
for (int j = 0; j < pts_on_curves[i]->Count(); j++)
(*pts_on_curves[i])[j]->m_rank = j;
}
- // Determine whether it's going inside or outside.
+
+ // Determine whether it's going inside or outside
(IntersectPoint::m_in_out).
for (int i = 0; i < curves.Count(); i++) {
for (int j = 0; j < pts_on_curves[i]->Count(); j++) {
IntersectPoint* ipt = (*pts_on_curves[i])[j];
if (pts_on_curves[i]->Count() < 2)
ipt->m_in_out = IntersectPoint::UNSET;
else {
- 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);
+ 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);
// 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
@@ -531,9 +580,9 @@
ipt->m_in_out = IntersectPoint::UNSET;
continue;
}
- if (j == 0 && ON_NearZero(ipt->m_t_for_rank -
curves[i]->Domain().Min())) {
+ if (j == 0 && ON_NearZero(ipt->m_t_for_rank -
curves[i].m_curve->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]->Domain().Max())) {
+ } else if (j == pts_on_curves[i]->Count() - 1 &&
ON_NearZero(ipt->m_t_for_rank - curves[i].m_curve->Domain().Max())) {
ipt->m_in_out = left_in ? IntersectPoint::OUT :
IntersectPoint::IN;
} else {
if (left_in && right_in) {
@@ -727,7 +776,7 @@
std::swap(t1, t2);
need_reverse = false;
}
- ON_Curve* seg_on_SSI = sub_curve(curves[p.m_type], t1, t2);
+ ON_Curve* seg_on_SSI = sub_curve(curves[p.m_type].m_curve, t1, t2);
if (seg_on_SSI == NULL) {
bu_log("sub_curve() failed.\n");
continue;
@@ -764,6 +813,8 @@
while (k < outerloop_start_end.Count()) {
outerloop_start_end.Remove();
}
+ // Update curves_from_ssi
+ curves_from_ssi.Append(curves[p.m_type]);
#endif
// Update m_pos
for (int j = i + 1; j < intersect.Count(); j++)
@@ -780,6 +831,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());
#endif
out.Append(newface);
}
@@ -823,6 +875,8 @@
for (int i = 0; i < outerloop_start_end.Count(); i++)
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());
#endif
out.Append(newface);
}
@@ -1004,7 +1058,7 @@
{
int facecount1 = brepA->m_F.Count();
int facecount2 = brepB->m_F.Count();
- ON_ClassArray<ON_SimpleArray<ON_Curve*> > curvesarray(facecount1 +
facecount2);
+ ON_ClassArray<ON_SimpleArray<SSICurve> > curvesarray(facecount1 +
facecount2);
// calculate intersection curves
for (int i = 0; i < facecount1; i++) {
@@ -1023,15 +1077,22 @@
|| events[k].m_type == ON_SSX_EVENT::ssx_transverse) {
if (get_subcurve_inside_faces(brepA, brepB, i, j,
&events[k]) < 0)
continue;
- curve_uv.Append(events[k].m_curveA);
- curve_st.Append(events[k].m_curveB);
+ SSICurve c1, c2;
+ c1.m_curve = events[k].m_curveA;
+ c2.m_curve = events[k].m_curveB;
+#if USE_CONNECTIVITY_GRAPH
+ c1.m_info.m_fi1 = i;
+ c1.m_info.m_fi2 = j;
+ c1.m_info.m_ci = k;
+ c2.m_info = c1.m_info;
+#endif
+ curvesarray[i].Append(c1);
+ curvesarray[facecount1 + j].Append(c2);
// Set m_curveA and m_curveB to NULL, in case that they are
// deleted by ~ON_SSX_EVENT().
events[k].m_curveA = events[k].m_curveB = NULL;
}
}
- curvesarray[i].Append(curve_uv.Count(), curve_uv.Array());
- curvesarray[facecount1 + j].Append(curve_st.Count(),
curve_st.Array());
}
}
@@ -1104,7 +1165,7 @@
ON_ClassArray<ON_SimpleArray<TrimmedFace*> > trimmedfaces;
for (int i = 0; i < original_faces.Count(); i++) {
TrimmedFace* first = original_faces[i];
- ON_SimpleArray<ON_Curve*> linked_curves;
+ ON_ClassArray<LinkedCurve> linked_curves;
link_curves(curvesarray[i], linked_curves);
ON_SimpleArray<TrimmedFace*> splitted;
split_trimmed_face(splitted, first, linked_curves);
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