Revision: 56573
http://sourceforge.net/p/brlcad/code/56573
Author: phoenixyjll
Date: 2013-08-05 12:50:54 +0000 (Mon, 05 Aug 2013)
Log Message:
-----------
Start to work on evaluating NURBS booleans. Move the code working with NURBS
booleans in librt to libbrep.
Modified Paths:
--------------
brlcad/trunk/include/brep.h
brlcad/trunk/src/libbrep/CMakeLists.txt
brlcad/trunk/src/librt/primitives/brep/brep.cpp
Added Paths:
-----------
brlcad/trunk/src/libbrep/boolean.cpp
Modified: brlcad/trunk/include/brep.h
===================================================================
--- brlcad/trunk/include/brep.h 2013-08-05 07:16:20 UTC (rev 56572)
+++ brlcad/trunk/include/brep.h 2013-08-05 12:50:54 UTC (rev 56573)
@@ -1733,9 +1733,12 @@
DumpSSXEvent(ON_SSX_EVENT &x, ON_TextLog &text_log);
/**
- * Sub-division support for curves and surfaces
+ * Sub-division support for curves
*/
class BREP_EXPORT Subcurve;
+/*
+ * Sub-division support for surfaces
+ */
class BREP_EXPORT Subsurface;
/* The ON_PX_EVENT class is used to report point-point, point-curve
@@ -2084,9 +2087,8 @@
* optional surface tree for surfaceB, to avoid re-computation
*
* Returns:
- * Number of intersection events appended to x. -1 for error.
+ * Number of intersection events appended to x.
*/
-
extern BREP_EXPORT int
ON_Intersect(const ON_Surface* surfA,
const ON_Surface* surfB,
@@ -2101,6 +2103,23 @@
Subsurface* treeA = 0,
Subsurface* treeB = 0);
+
+/**
+ * Evaluate NURBS boolean operations.
+ *
+ * Parameters:
+ *
+ * brepO - [out]
+ *
+ * brepA - [in]
+ *
+ * brepB - [in]
+ *
+ * operation - [in]
+ */
+extern BREP_EXPORT int
+ON_Boolean(ON_Brep* brepO, const ON_Brep* brepA, const ON_Brep* brepB, int
operation);
+
} /* extern C++ */
#endif
Modified: brlcad/trunk/src/libbrep/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libbrep/CMakeLists.txt 2013-08-05 07:16:20 UTC (rev
56572)
+++ brlcad/trunk/src/libbrep/CMakeLists.txt 2013-08-05 12:50:54 UTC (rev
56573)
@@ -19,6 +19,7 @@
BRLCAD_LIB_INCLUDE_DIRS(brep BREP_INCLUDE_DIRS BREP_LOCAL_INCLUDE_DIRS)
set(LIBBREP_SOURCES
+ boolean.cpp
intersect.cpp
libbrep_brep_tools.cpp
opennurbs_ext.cpp
Added: brlcad/trunk/src/libbrep/boolean.cpp
===================================================================
--- brlcad/trunk/src/libbrep/boolean.cpp (rev 0)
+++ brlcad/trunk/src/libbrep/boolean.cpp 2013-08-05 12:50:54 UTC (rev
56573)
@@ -0,0 +1,571 @@
+/* B O O L E A N . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 2013 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file boolean.cpp
+ *
+ * Evaluate NURBS booleans (union, intersection and difference).
+ *
+ */
+
+#include "common.h"
+
+#include <assert.h>
+#include <vector>
+#include <stack>
+#include <algorithm>
+#include "bio.h"
+
+#include "vmath.h"
+#include "bu.h"
+
+#include "brep.h"
+#include "raytrace.h"
+
+
+int
+curve_intersect(const ON_NurbsCurve *curveA,
+ const ON_NurbsCurve *curveB,
+ ON_3dPointArray *intersect,
+ ON_SimpleArray<std::pair<int, int> > *CV,
+ ON_SimpleArray<std::pair<double, double> > *parameter)
+{
+ int countA = curveA->CVCount();
+ int countB = curveB->CVCount();
+ for (int i = 0; i < countA - 1; i++) {
+ ON_3dPoint fromA, toA;
+ curveA->GetCV(i, fromA);
+ curveA->GetCV(i + 1, toA);
+ ON_Line lineA(fromA, toA);
+ for (int j = 0; j < countB - 1; j++) {
+ ON_3dPoint fromB, toB;
+ curveB->GetCV(j, fromB);
+ curveB->GetCV(j + 1, toB);
+ ON_Line lineB(fromB, toB);
+ double tA, tB;
+ if (ON_Intersect(lineA, lineB, &tA, &tB) != true)
+ continue;
+ if (tA >= 0.0 && tA <= 1.0 && tB >= 0.0 && tB <= 1.0) {
+ intersect->Append(lineA.PointAt(tA));
+ CV->Append(std::make_pair(i, j));
+ parameter->Append(std::make_pair(tA, tB));
+ }
+ }
+ }
+ return 0;
+}
+
+
+int
+split_curve(ON_NurbsCurve *out1, ON_NurbsCurve *out2, const ON_NurbsCurve
*curve, const int CVindex, const double t)
+{
+ if (out1 == NULL || out2 == NULL)
+ return -1;
+
+ // Split the curve using polyline curves.
+ ON_3dPointArray pts1, pts2;
+ for (int i = 0; i <= CVindex; i++) {
+ ON_3dPoint point;
+ curve->GetCV(i, point);
+ pts1.Append(point);
+ }
+ ON_3dPoint start, end;
+ curve->GetCV(CVindex, start);
+ curve->GetCV(CVindex + 1, end);
+ ON_Line line(start, end);
+ pts1.Append(line.PointAt(t));
+ pts2.Append(line.PointAt(t));
+ for (int i = CVindex + 1; i < curve->CVCount(); i++) {
+ ON_3dPoint point;
+ curve->GetCV(i, point);
+ pts2.Append(point);
+ }
+
+ ON_PolylineCurve poly1(pts1), poly2(pts2);
+ poly1.GetNurbForm(*out1);
+ poly2.GetNurbForm(*out2);
+ return 0;
+}
+
+
+struct TrimmedFace {
+ ON_SimpleArray<ON_NurbsCurve*> outerloop;
+ ON_SimpleArray<ON_NurbsCurve*> innerloop;
+ const ON_BrepFace *face;
+ TrimmedFace *Duplicate() const
+ {
+ TrimmedFace *out = new TrimmedFace();
+ out->face = face;
+ out->outerloop = outerloop;
+ out->innerloop = innerloop;
+ return out;
+ }
+};
+
+
+struct IntersectPoint {
+ ON_3dPoint m_pt;
+ int m_seg;
+ int m_t;
+ int m_type;
+ int m_rank;
+ int m_seg_for_rank;
+ int m_t_for_rank;
+ bool m_in_out;
+ std::list<ON_3dPoint>::iterator m_pos;
+};
+
+
+int
+compare_seg_t(IntersectPoint* const *a, IntersectPoint* const *b)
+{
+ if ((*a)->m_seg != (*b)->m_seg)
+ return (*a)->m_seg - (*b)->m_seg;
+ return (*a)->m_t - (*b)->m_t;
+}
+
+
+int
+compare_for_rank(IntersectPoint* const *a, IntersectPoint* const *b)
+{
+ if ((*a)->m_seg_for_rank != (*b)->m_seg_for_rank)
+ return (*a)->m_seg_for_rank - (*b)->m_seg_for_rank;
+ return (*a)->m_t_for_rank - (*b)->m_t_for_rank;
+}
+
+
+int
+split_trimmed_face(ON_SimpleArray<TrimmedFace*> &out, const TrimmedFace *in,
const ON_SimpleArray<ON_NurbsCurve*> &curves)
+{
+ /* We followed the algorithms described in:
+ * S. Krishnan, A. Narkhede, and D. Manocha. BOOLE: A System to Compute
+ * Boolean Combinations of Sculptured Solids. Technical Report TR95-008,
+ * Department of Computer Science, University of North Carolina, 1995.
+ * Appendix B: Partitioning a Simple Polygon using Non-Intersecting
+ * Chains.
+ */
+
+ if (curves.Count() == 0) {
+ // No curve, no splitting
+ out.Append(in->Duplicate());
+ return 0;
+ }
+
+ ON_SimpleArray<IntersectPoint> intersect;
+ ON_SimpleArray<bool> have_intersect(curves.Count());
+ for (int i = 0; i < curves.Count(); i++)
+ have_intersect[i] = false;
+
+ int CVCount_sum = 0;
+ for (int i = 0; i < in->outerloop.Count(); i++) {
+ for (int j = 0; j < curves.Count(); j++) {
+ ON_3dPointArray intersect_pt;
+ ON_SimpleArray<std::pair<int, int> > CV;
+ ON_SimpleArray<std::pair<double, double> > parameter;
+ curve_intersect(in->outerloop[i], curves[j], &intersect_pt, &CV,
¶meter);
+ for (int k = 0; k < intersect_pt.Count(); k++) {
+ IntersectPoint tmp_pt;
+ tmp_pt.m_pt = intersect_pt[k];
+ tmp_pt.m_seg = CVCount_sum + CV[k].first;
+ tmp_pt.m_t = (int)parameter[k].first;
+ tmp_pt.m_type = j;
+ tmp_pt.m_seg_for_rank = CV[k].second;
+ tmp_pt.m_t_for_rank = (int)parameter[k].second;
+ intersect.Append(tmp_pt);
+ }
+ if (intersect_pt.Count())
+ have_intersect[j] = true;
+ }
+ CVCount_sum += in->outerloop[i]->CVCount();
+ }
+
+ // deal with the situations where there is no intersection
+ for (int i = 0; i < curves.Count(); i++) {
+ if (!have_intersect[i]) {
+ ON_BoundingBox bbox_outerloop;
+ for (int j = 0; j < in->outerloop.Count(); j++) {
+ bbox_outerloop.Union(in->outerloop[j]->BoundingBox());
+ }
+ if (bbox_outerloop.Includes(curves[i]->BoundingBox())) {
+ if (curves[i]->IsClosed()) {
+ TrimmedFace *newface = in->Duplicate();
+ newface->innerloop.Append(curves[i]);
+ out.Append(newface);
+ newface = new TrimmedFace();
+ newface->face = in->face;
+ newface->outerloop.Append(curves[i]);
+ out.Append(newface);
+ }
+ }
+ }
+ }
+
+ // rank these intersection points
+ ON_SimpleArray<ON_SimpleArray<IntersectPoint*>*>
pts_on_curves(curves.Count());
+ ON_SimpleArray<IntersectPoint*> sorted_pointers;
+ for (int i = 0; i < curves.Count(); i++)
+ pts_on_curves[i] = new ON_SimpleArray<IntersectPoint*>();
+ for (int i = 0; i < intersect.Count(); i++) {
+ pts_on_curves[intersect[i].m_type]->Append(&(intersect[i]));
+ sorted_pointers.Append(&(intersect[i]));
+ }
+ for (int i = 0; i < curves.Count(); i++) {
+ pts_on_curves[i]->QuickSort(compare_for_rank);
+ for (int j = 0; j < pts_on_curves[i]->Count(); j++)
+ (*pts_on_curves[i])[j]->m_rank = j;
+ }
+ for (int i = 0; i < curves.Count(); i++) {
+ delete pts_on_curves[i];
+ }
+ sorted_pointers.QuickSort(compare_seg_t);
+
+ for (int i = 0; i < intersect.Count(); i++) {
+ // We assume that the starting point is outside.
+ if (intersect[i].m_rank % 2 == 0) {
+ intersect[i].m_in_out = false; // in
+ } else {
+ intersect[i].m_in_out = true; // out
+ }
+ }
+
+ std::list<ON_3dPoint> outerloop;
+ int count = 0;
+ int isect_iter = 0;
+ for (int i = 0; i < in->outerloop.Count(); i++) {
+ const ON_NurbsCurve *curve_on_loop = in->outerloop[i];
+ for (int j = 0; j < curve_on_loop->CVCount(); j++) {
+ ON_3dPoint cvpt;
+ curve_on_loop->GetCV(j, cvpt);
+ outerloop.push_back(cvpt);
+ count++;
+ for (; isect_iter < sorted_pointers.Count() &&
sorted_pointers[isect_iter]->m_seg < count; isect_iter++) {
+ outerloop.push_back(sorted_pointers[isect_iter]->m_pt);
+ sorted_pointers[isect_iter]->m_pos = --outerloop.end();
+ }
+ }
+ }
+ outerloop.push_back(in->outerloop[0]->PointAtStart());
+
+ std::stack<int> s;
+ s.push(0);
+ for (int i = 1; i < sorted_pointers.Count(); i++) {
+ if (s.empty()) {
+ s.push(i);
+ continue;
+ }
+ IntersectPoint *p = sorted_pointers[s.top()];
+ IntersectPoint *q = sorted_pointers[i];
+ if (q->m_type != p->m_type) {
+ s.push(i);
+ continue;
+ } else if (q->m_rank - p->m_rank == 1 && q->m_in_out == false &&
p->m_in_out == true) {
+ s.pop();
+ } else if (p->m_rank - q->m_rank == 1 && p->m_in_out == false &&
q->m_in_out == true) {
+ s.pop();
+ } else {
+ s.push(i);
+ continue;
+ }
+
+ // need to form a new loop
+ if (compare_seg_t(&p, &q) > 0)
+ std::swap(p, q);
+ ON_3dPointArray newloop;
+ std::list<ON_3dPoint> newsegment;
+ std::list<ON_3dPoint>::iterator iter;
+ for (iter = p->m_pos; iter != q->m_pos; iter++) {
+ newloop.Append(*iter);
+ }
+ newloop.Append(q->m_pt);
+ if (p->m_seg_for_rank < q->m_seg_for_rank) {
+ for (int j = p->m_seg_for_rank + 1; j <= q->m_seg_for_rank; j++) {
+ ON_3dPoint cvpt;
+ curves[p->m_type]->GetCV(j, cvpt);
+ newloop.Append(cvpt);
+ newsegment.push_back(cvpt);
+ }
+ } else if (p->m_seg_for_rank > q->m_seg_for_rank) {
+ for (int j = p->m_seg_for_rank; j > q->m_seg_for_rank; j--) {
+ ON_3dPoint cvpt;
+ curves[p->m_type]->GetCV(j, cvpt);
+ newloop.Append(cvpt);
+ newsegment.push_back(cvpt);
+ }
+ }
+ newloop.Append(p->m_pt);
+
+ // Append a surface with newloop as its outerloop
+ ON_PolylineCurve polycurve(newloop);
+ ON_NurbsCurve *nurbscurve = ON_NurbsCurve::New();
+ polycurve.GetNurbForm(*nurbscurve);
+ TrimmedFace *newface = new TrimmedFace();
+ newface->face = in->face;
+ newface->outerloop.Append(nurbscurve);
+
+ // adjust the outerloop
+ std::list<ON_3dPoint>::iterator first = p->m_pos;
+ outerloop.erase(++first, q->m_pos);
+ first = p->m_pos;
+ outerloop.insert(++first, newsegment.begin(), newsegment.end());
+ }
+
+ // WIP
+ // The follows commented out are out of date.
+ /* if (sum == 0) {
+ // no intersection points with the outerloop
+ ON_BoundingBox bbox_outerloop;
+ for (int i = 0; i < in->outerloop.Count(); i++) {
+ bbox_outerloop.Union(in->outerloop[i].BoundingBox());
+ }
+ if (bbox_outerloop.Includes(curve->BoundingBox())) {
+ if (curve->IsClosed()) {
+ TrimmedFace *newface = in->Duplicate();
+ newface->innerloop.Append(*curve);
+ out.Append(newface);
+ newface = new TrimmedFace();
+ newface->face = in->face;
+ newface->outerloop.Append(*curve);
+ out.Append(newface);
+ return 0;
+ }
+ }
+ } else if (sum >= 2) {
+ // intersect the outerloop (TODO)
+ // Now we only consider sum == 2 and the two intersection points are
+ // not on the same curve of the outer loop.
+ int start = -1;
+ for (int i = 0; i < intersect.Count(); i++) {
+ if (intersect[i].Count() != 0) {
+ start = i;
+ break;
+ }
+ }
+ TrimmedFace *newface = new TrimmedFace();
+ newface->face = in->face;
+ ON_NurbsCurve curve1, curve2;
+ split_curve(&curve1, &curve2, &(in->outerloop[start]),
CV[start][0].first, parameter[start][0][0]);
+ newface->outerloop.Append(curve2);
+ int i;
+ for (i = start + 1; i != start; i = (i+1)%intersect.Count()) {
+ if (intersect[i].Count() == 0) {
+ newface->outerloop.Append(in->outerloop[i]);
+ } else {
+ break;
+ }
+ }
+ ON_NurbsCurve curve3, curve4;
+ split_curve(&curve3, &curve4, &(in->outerloop[i]), CV[i][0].first,
parameter[i][0][0]);
+ newface->outerloop.Append(curve3);
+ newface->outerloop.Append(*curve);
+ out.Append(newface);
+ newface = new TrimmedFace();
+ newface->face = in->face;
+ newface->outerloop.Append(curve4);
+ for (; i != start; i = (i+1)%intersect.Count()) {
+ if (intersect[i].Count() == 0) {
+ newface->outerloop.Append(in->outerloop[i]);
+ }
+ }
+ newface->outerloop.Append(curve1);
+ newface->outerloop.Append(*curve);
+ out.Append(newface);
+ return 0;
+ }*/
+
+ if (out.Count() == 0) {
+ out.Append(in->Duplicate());
+ }
+ bu_log("Split to %d faces.\n", out.Count());
+ return 0;
+}
+
+
+void
+add_elements(ON_Brep *brep, ON_BrepFace &face, ON_SimpleArray<ON_NurbsCurve*>
&loop, ON_BrepLoop::TYPE loop_type)
+{
+ if (!loop.Count())
+ return;
+
+ ON_BrepLoop &breploop = brep->NewLoop(loop_type, face);
+ int start_index = brep->m_V.Count();
+ for (int k = 0; k < loop.Count(); k++) {
+ int ti = brep->AddTrimCurve(loop[k]);
+ ON_2dPoint start = loop[k]->PointAtStart(), end = loop[k]->PointAtEnd();
+ ON_BrepVertex& start_v = k > 0 ? brep->m_V[brep->m_V.Count() - 1] :
+ brep->NewVertex(face.SurfaceOf()->PointAt(start.x, start.y), 0.0);
+ ON_BrepVertex& end_v = loop[k]->IsClosed() ? start_v :
+ brep->NewVertex(face.SurfaceOf()->PointAt(end.x, end.y), 0.0);
+ if (k == loop.Count() - 1) {
+ if (!loop[k]->IsClosed())
+ brep->m_V.Remove(brep->m_V.Count() - 1);
+ end_v = brep->m_V[start_index];
+ }
+ int start_idx = start_v.m_vertex_index;
+ int end_idx = end_v.m_vertex_index;
+
+ ON_NurbsCurve *c3d = ON_NurbsCurve::New();
+ // First, try the ON_Surface::Pushup() method.
+ // If Pushup() does not succeed, use sampling method.
+ ON_Curve *curve_pt = face.SurfaceOf()->Pushup(*(loop[k]), 1e-3);
+ if (curve_pt) {
+ curve_pt->GetNurbForm(*c3d);
+ delete curve_pt;
+ } else if (loop[k]->CVCount() == 2) {
+ // A closed curve with two control points
+ // TODO: Sometimes we need a singular trim.
+ ON_3dPointArray ptarray(101);
+ for (int l = 0; l <= 100; l++) {
+ ON_3dPoint pt2d;
+ pt2d =
loop[k]->PointAt(loop[k]->Domain().NormalizedParameterAt(l/100.0));
+ ptarray.Append(face.SurfaceOf()->PointAt(pt2d.x, pt2d.y));
+ }
+ ON_PolylineCurve polycurve(ptarray);
+ polycurve.GetNurbForm(*c3d);
+ } else {
+ delete c3d;
+ c3d = loop[k]->Duplicate();
+ c3d->ChangeDimension(3);
+ for (int l = 0; l < loop[k]->CVCount(); l++) {
+ ON_3dPoint pt2d;
+ loop[k]->GetCV(l, pt2d);
+ ON_3dPoint pt3d = face.SurfaceOf()->PointAt(pt2d.x, pt2d.y);
+ c3d->SetCV(l, pt3d);
+ }
+ }
+ brep->AddEdgeCurve(c3d);
+ ON_BrepEdge &edge = brep->NewEdge(brep->m_V[start_idx],
brep->m_V[end_idx],
+ brep->m_C3.Count() - 1, (const ON_Interval *)0, MAX_FASTF);
+ ON_BrepTrim &trim = brep->NewTrim(edge, 0, breploop, ti);
+ trim.m_tolerance[0] = trim.m_tolerance[1] = MAX_FASTF;
+
+ // TODO: Deal with split seam trims to pass ON_Brep::IsValid()
+ }
+ if (brep->m_V.Count() < brep->m_V.Capacity())
+ brep->m_V[brep->m_V.Count()].m_ei.Empty();
+}
+
+
+int
+ON_Boolean(ON_Brep* brepO, const ON_Brep* brepA, const ON_Brep* brepB, int
UNUSED(operation))
+{
+ int facecount1 = brepA->m_F.Count();
+ int facecount2 = brepB->m_F.Count();
+ ON_SimpleArray<ON_NurbsCurve *> *curvesarray = new
ON_SimpleArray<ON_NurbsCurve *> [facecount1 + facecount2];
+
+ // calculate intersection curves
+ for (int i = 0; i < facecount1; i++) {
+ for (int j = 0; j < facecount2; j++) {
+ ON_ClassArray<ON_SSX_EVENT> events;
+ if (ON_Intersect(brepA->m_S[brepA->m_F[i].m_si],
+ brepB->m_S[brepB->m_F[j].m_si],
+ events) <= 0)
+ continue;
+ ON_SimpleArray<ON_NurbsCurve *> curve_uv, curve_st;
+ for (int k = 0; k < events.Count(); k++) {
+ ON_NurbsCurve *nurbscurve = ON_NurbsCurve::New();
+ events[k].m_curveA->GetNurbForm(*nurbscurve);
+ curve_uv.Append(nurbscurve);
+ nurbscurve = ON_NurbsCurve::New();
+ events[k].m_curveA->GetNurbForm(*nurbscurve);
+ curve_st.Append(nurbscurve);
+ }
+ curvesarray[i].Append(curve_uv.Count(), curve_uv.Array());
+ curvesarray[facecount1 + j].Append(curve_st.Count(),
curve_st.Array());
+ }
+ }
+
+ // split the surfaces with the intersection curves
+ for (int i = 0; i < facecount1 + facecount2; i++) {
+ ON_SimpleArray<ON_NurbsCurve*> innercurves, outercurves;
+ const ON_BrepFace &face = i < facecount1 ? brepA->m_F[i] : brepB->m_F[i
- facecount1];
+ const ON_Brep *brep = i < facecount1 ? brepA : brepB;
+ const ON_SimpleArray<int> &loopindex = face.m_li;
+ for (int j = 0; j < loopindex.Count(); j++) {
+ const ON_BrepLoop &loop = brep->m_L[loopindex[j]];
+ const ON_SimpleArray<int> &trimindex = loop.m_ti;
+ for (int k = 0; k < trimindex.Count(); k++) {
+ ON_Curve *curve2d = brepA->m_C2[brep->m_T[trimindex[k]].m_c2i];
+ ON_NurbsCurve *nurbscurve = ON_NurbsCurve::New();
+ if (!curve2d->GetNurbForm(*nurbscurve))
+ continue;
+ if (j == 0) {
+ outercurves.Append(nurbscurve);
+ } else {
+ innercurves.Append(nurbscurve);
+ }
+ }
+ }
+ ON_SimpleArray<TrimmedFace*> trimmedfaces;
+ TrimmedFace *first = new TrimmedFace();
+ first->face = &face;
+ first->innerloop = innercurves;
+ first->outerloop = outercurves;
+ split_trimmed_face(trimmedfaces, first, curvesarray[i]);
+
+ /* TODO: Perform inside-outside test to decide whether the trimmed face
+ * should be used in the final b-rep structure or not.
+ * Different operations should be dealt with accordingly.
+ * Another solution is to use connectivity graphs which represents the
+ * topological structure of the b-rep. This can reduce time-consuming
+ * inside-outside tests.
+ * Here we just use all of these trimmed faces.
+ */
+ for (int j = 0; j < trimmedfaces.Count(); j++) {
+ // Add the surfaces, faces, loops, trims, vertices, edges, etc.
+ // to the brep structure.
+ ON_Surface *new_surf = face.SurfaceOf()->Duplicate();
+ int surfindex = brepO->AddSurface(new_surf);
+ ON_BrepFace& new_face = brepO->NewFace(surfindex);
+
+ add_elements(brepO, new_face, trimmedfaces[j]->outerloop,
ON_BrepLoop::outer);
+ ON_BrepLoop &loop = brepO->m_L[brepO->m_L.Count() - 1];
+ add_elements(brepO, new_face, trimmedfaces[j]->innerloop,
ON_BrepLoop::inner);
+
+ new_surf->SetDomain(0, loop.m_pbox.m_min.x, loop.m_pbox.m_max.x);
+ new_surf->SetDomain(1, loop.m_pbox.m_min.y, loop.m_pbox.m_max.y);
+ brepO->SetTrimIsoFlags(new_face);
+ brepO->FlipFace(new_face);
+ }
+ }
+
+ // Check IsValid() and output the message.
+ ON_wString ws;
+ ON_TextLog log(ws);
+ brepO->IsValid(&log);
+ char *s = new char [ws.Length() + 1];
+ for (int k = 0; k < ws.Length(); k++) {
+ s[k] = ws[k];
+ }
+ s[ws.Length()] = 0;
+ bu_log("%s", s);
+ delete s;
+
+ // WIP
+ delete [] curvesarray;
+ return 0;
+}
+
+
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
\ No newline at end of file
Property changes on: brlcad/trunk/src/libbrep/boolean.cpp
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: brlcad/trunk/src/librt/primitives/brep/brep.cpp
===================================================================
--- brlcad/trunk/src/librt/primitives/brep/brep.cpp 2013-08-05 07:16:20 UTC
(rev 56572)
+++ brlcad/trunk/src/librt/primitives/brep/brep.cpp 2013-08-05 12:50:54 UTC
(rev 56573)
@@ -4073,7 +4073,7 @@
int
-rt_brep_boolean(struct rt_db_internal *out, const struct rt_db_internal *ip1,
const struct rt_db_internal *ip2, const int UNUSED(operation))
+rt_brep_boolean(struct rt_db_internal *out, const struct rt_db_internal *ip1,
const struct rt_db_internal *ip2, const int operation)
{
RT_CK_DB_INTERNAL(ip1);
RT_CK_DB_INTERNAL(ip2);
@@ -4088,98 +4088,10 @@
brep2 = bip2->brep;
brep_out = ON_Brep::New();
- int facecount1 = brep1->m_F.Count();
- int facecount2 = brep2->m_F.Count();
- ON_SimpleArray<ON_NurbsCurve *> *curvesarray = new
ON_SimpleArray<ON_NurbsCurve *> [facecount1 + facecount2];
+ int ret;
+ if ((ret = ON_Boolean(brep_out, brep1, brep2, operation)) < 0)
+ return ret;
- // calculate intersection curves
- for (int i = 0; i < facecount1; i++) {
- for (int j = 0; j < facecount2; j++) {
- ON_ClassArray<ON_SSX_EVENT> events;
- if (ON_Intersect(brep1->m_S[brep1->m_F[i].m_si],
- brep2->m_S[brep2->m_F[j].m_si],
- events) <= 0)
- continue;
- ON_SimpleArray<ON_NurbsCurve *> curve_uv, curve_st;
- for (int k = 0; k < events.Count(); k++) {
- ON_NurbsCurve *nurbscurve = ON_NurbsCurve::New();
- events[k].m_curveA->GetNurbForm(*nurbscurve);
- curve_uv.Append(nurbscurve);
- nurbscurve = ON_NurbsCurve::New();
- events[k].m_curveA->GetNurbForm(*nurbscurve);
- curve_st.Append(nurbscurve);
- }
- curvesarray[i].Append(curve_uv.Count(), curve_uv.Array());
- curvesarray[facecount1 + j].Append(curve_st.Count(),
curve_st.Array());
- }
- }
-
- // split the surfaces with the intersection curves
- for (int i = 0; i < facecount1 + facecount2; i++) {
- ON_SimpleArray<ON_NurbsCurve*> innercurves, outercurves;
- ON_BrepFace &face = i < facecount1 ? brep1->m_F[i] : brep2->m_F[i -
facecount1];
- ON_Brep *brep = i < facecount1 ? brep1 : brep2;
- ON_SimpleArray<int> &loopindex = face.m_li;
- for (int j = 0; j < loopindex.Count(); j++) {
- ON_BrepLoop &loop = brep->m_L[loopindex[j]];
- ON_SimpleArray<int> &trimindex = loop.m_ti;
- for (int k = 0; k < trimindex.Count(); k++) {
- ON_Curve *curve2d = brep1->m_C2[brep->m_T[trimindex[k]].m_c2i];
- ON_NurbsCurve *nurbscurve = ON_NurbsCurve::New();
- if (!curve2d->GetNurbForm(*nurbscurve))
- continue;
- if (j == 0) {
- outercurves.Append(nurbscurve);
- } else {
- innercurves.Append(nurbscurve);
- }
- }
- }
- ON_SimpleArray<TrimmedFace*> trimmedfaces;
- TrimmedFace *first = new TrimmedFace();
- first->face = &face;
- first->innerloop = innercurves;
- first->outerloop = outercurves;
- split_trimmed_face(trimmedfaces, first, curvesarray[i]);
-
- /* TODO: Perform inside-outside test to decide whether the trimmed face
- * should be used in the final b-rep structure or not.
- * Different operations should be dealt with accordingly.
- * Another solution is to use connectivity graphs which represents the
- * topological structure of the b-rep. This can reduce time-consuming
- * inside-outside tests.
- * Here we just use all of these trimmed faces.
- */
- for (int j = 0; j < trimmedfaces.Count(); j++) {
- // Add the surfaces, faces, loops, trims, vertices, edges, etc.
- // to the brep structure.
- ON_Surface *new_surf = face.SurfaceOf()->Duplicate();
- int surfindex = brep_out->AddSurface(new_surf);
- ON_BrepFace& new_face = brep_out->NewFace(surfindex);
-
- add_elements(brep_out, new_face, trimmedfaces[j]->outerloop,
ON_BrepLoop::outer);
- ON_BrepLoop &loop = brep_out->m_L[brep_out->m_L.Count() - 1];
- add_elements(brep_out, new_face, trimmedfaces[j]->innerloop,
ON_BrepLoop::inner);
-
- new_surf->SetDomain(0, loop.m_pbox.m_min.x, loop.m_pbox.m_max.x);
- new_surf->SetDomain(1, loop.m_pbox.m_min.y, loop.m_pbox.m_max.y);
- brep_out->SetTrimIsoFlags(new_face);
- brep_out->FlipFace(new_face);
- }
- }
-
- // Check IsValid() and output the message.
- ON_wString ws;
- ON_TextLog log(ws);
- brep_out->IsValid(&log);
- char *s = new char [ws.Length() + 1];
- for (int k = 0; k < ws.Length(); k++) {
- s[k] = ws[k];
- }
- s[ws.Length()] = 0;
- bu_log("%s", s);
- delete s;
-
// make the final rt_db_internal
struct rt_brep_internal *bip_out;
BU_ALLOC(bip_out, struct rt_brep_internal);
@@ -4191,8 +4103,6 @@
out->idb_meth = &OBJ[ID_BREP];
out->idb_minor_type = ID_BREP;
- // WIP
- delete [] curvesarray;
return 0;
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits