Revision: 41533
http://brlcad.svn.sourceforge.net/brlcad/?rev=41533&view=rev
Author: indianlarry
Date: 2010-12-07 15:43:14 +0000 (Tue, 07 Dec 2010)
Log Message:
-----------
Added special wire-frame drawing routines for surfaces who's 3D edges tend to
yield a poor graphical representation. These special drawing routines relate to
extruded, revolved and closed surfaces and use the surface subdivision tree. To
improve performance added a 'depthLimit' parameter to surface subdivision
routines for use in wire-frame approximation.
Modified Paths:
--------------
brlcad/trunk/include/opennurbs_ext.h
brlcad/trunk/src/librt/opennurbs_ext.cpp
brlcad/trunk/src/librt/primitives/brep/brep.cpp
brlcad/trunk/src/librt/primitives/brep/brep_debug.cpp
Modified: brlcad/trunk/include/opennurbs_ext.h
===================================================================
--- brlcad/trunk/include/opennurbs_ext.h 2010-12-07 14:00:50 UTC (rev
41532)
+++ brlcad/trunk/include/opennurbs_ext.h 2010-12-07 15:43:14 UTC (rev
41533)
@@ -1396,7 +1396,7 @@
bool m_removeTrimmed;
public:
- SurfaceTree(ON_BrepFace* face, bool removeTrimmed=true);
+ SurfaceTree(ON_BrepFace* face, bool removeTrimmed=true, int depthLimit =
BREP_MAX_FT_DEPTH);
~SurfaceTree();
CurveTree* ctree;
@@ -1427,8 +1427,8 @@
bool isFlat(const ON_Surface* surf, ON_Plane frames[], ON_3dVector
normals[], ON_3dPoint corners[], const ON_Interval& u, const ON_Interval& v);
fastf_t isFlatU(const ON_Surface* surf, ON_Plane frames[], ON_3dVector
normals[], ON_3dPoint corners[], const ON_Interval& u, const ON_Interval& v);
fastf_t isFlatV(const ON_Surface* surf, ON_Plane frames[], ON_3dVector
normals[], ON_3dPoint corners[], const ON_Interval& u, const ON_Interval& v);
- BBNode* subdivideSurfaceByKnots(const ON_Surface *localsurf, const
ON_Interval& u, const ON_Interval& v, ON_Plane frames[], ON_3dPoint corners[],
ON_3dVector normals[], int depth);
- BBNode* subdivideSurface(const ON_Surface *localsurf, const ON_Interval&
u, const ON_Interval& v, ON_Plane frames[], ON_3dPoint corners[], ON_3dVector
normals[], int depth);
+ BBNode* subdivideSurfaceByKnots(const ON_Surface *localsurf, const
ON_Interval& u, const ON_Interval& v, ON_Plane frames[], ON_3dPoint corners[],
ON_3dVector normals[], int depth, int depthLimit);
+ BBNode* subdivideSurface(const ON_Surface *localsurf, const ON_Interval&
u, const ON_Interval& v, ON_Plane frames[], ON_3dPoint corners[], ON_3dVector
normals[], int depth, int depthLimit);
BBNode* surfaceBBox(const ON_Surface *localsurf, bool leaf, ON_3dPoint
corners[], ON_3dVector normals[], const ON_Interval& u, const ON_Interval& v);
ON_BrepFace* m_face;
Modified: brlcad/trunk/src/librt/opennurbs_ext.cpp
===================================================================
--- brlcad/trunk/src/librt/opennurbs_ext.cpp 2010-12-07 14:00:50 UTC (rev
41532)
+++ brlcad/trunk/src/librt/opennurbs_ext.cpp 2010-12-07 15:43:14 UTC (rev
41533)
@@ -594,7 +594,7 @@
//--------------------------------------------------------------------------------
// SurfaceTree
-SurfaceTree::SurfaceTree(ON_BrepFace* face, bool removeTrimmed)
+SurfaceTree::SurfaceTree(ON_BrepFace* face, bool removeTrimmed, int depthLimit)
: m_removeTrimmed(removeTrimmed),
m_face(face)
{
@@ -647,7 +647,7 @@
corners[8] = frames[8].origin;
normals[8] = frames[8].zaxis;
- m_root = subdivideSurfaceByKnots(surf, u, v, frames, corners, normals, 0);
+ m_root = subdivideSurfaceByKnots(surf, u, v, frames, corners, normals, 0,
depthLimit);
m_root->BuildBBox();
TRACE("u: [" << u[0] << ", " << u[1] << "]");
TRACE("v: [" << v[0] << ", " << v[1] << "]");
@@ -754,10 +754,11 @@
//bu_log("in c%d_%d sph %f %f %f %f\n", bb_cnt, i, m_corners[i].x,
m_corners[i].y, m_corners[i].z, 1.0);
}
+ //bu_log("in bb%d rpp %f %f %f %f %f %f\n", bb_cnt, min[0], max[0],
min[1], max[1], min[2], max[2]);
//VMOVE(min,bbox.Min());
//VMOVE(max,bbox.Max());
- //bu_log("in b%d rpp %f %f %f %f %f %f\n", bb_cnt, bbox.m_min.x,
bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z, bbox.m_max.z);
+ //bu_log("in b%d rpp %f %f %f %f %f %f\n", bb_cnt++, bbox.m_min.x,
bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z, bbox.m_max.z);
//bu_log("in bc%d rpp %f %f %f %f %f %f\n", bb_cnt++, min[0], max[0],
min[1], max[1], min[2], max[2]);
// calculate the estimate point on the surface: i.e. use the point
@@ -824,7 +825,8 @@
ON_Plane frames[],
ON_3dPoint corners[],
ON_3dVector normals[],
- int divDepth)
+ int divDepth,
+ int depthLimit)
{
const ON_Surface* surf = m_face->SurfaceOf();
ON_Interval usurf = surf->Domain(0);
@@ -857,9 +859,7 @@
corners[8] = frames[8].origin;
normals[8] = frames[8].zaxis;
- if (divDepth > 100) {
- return surfaceBBox(localsurf, true, corners, normals, u, v);
- } else if ((spanu_cnt > 1) && (spanv_cnt > 1)) {
+ if ((spanu_cnt > 1) && (spanv_cnt > 1)) {
double usplit = spanu[(spanu_cnt+1)/2];
double vsplit = spanv[(spanv_cnt+1)/2];
ON_Interval firstu(u.Min(), usplit);
@@ -992,7 +992,7 @@
newframes[4] = frames[5];
newcorners[4] = corners[5];
newnormals[4] = normals[5];
- quads[0] = subdivideSurfaceByKnots(q0surf, firstu, firstv,
newframes, newcorners, newnormals, divDepth+1);
+ quads[0] = subdivideSurfaceByKnots(q0surf, firstu, firstv,
newframes, newcorners, newnormals, divDepth+1, depthLimit);
delete q0surf;
newframes[0] = sharedframes[0];
newcorners[0] = sharedcorners[0];
@@ -1009,7 +1009,7 @@
newframes[4] = frames[7];
newcorners[4] = corners[7];
newnormals[4] = normals[7];
- quads[1] = subdivideSurfaceByKnots(q1surf, secondu, firstv,
newframes, newcorners, newnormals, divDepth+1);
+ quads[1] = subdivideSurfaceByKnots(q1surf, secondu, firstv,
newframes, newcorners, newnormals, divDepth+1, depthLimit);
delete q1surf;
newframes[0] = frames[4];
newcorners[0] = corners[4];
@@ -1026,7 +1026,7 @@
newframes[4] = frames[8];
newcorners[4] = corners[8];
newnormals[4] = normals[8];
- quads[2] = subdivideSurfaceByKnots(q2surf, secondu, secondv,
newframes, newcorners, newnormals, divDepth+1);
+ quads[2] = subdivideSurfaceByKnots(q2surf, secondu, secondv,
newframes, newcorners, newnormals, divDepth+1, depthLimit);
delete q2surf;
newframes[0] = sharedframes[1];
newcorners[0] = sharedcorners[1];
@@ -1043,7 +1043,7 @@
newframes[4] = frames[6];
newcorners[4] = corners[6];
newnormals[4] = normals[6];
- quads[3] = subdivideSurfaceByKnots(q3surf, firstu, secondv,
newframes, newcorners, newnormals, divDepth+1);
+ quads[3] = subdivideSurfaceByKnots(q3surf, firstu, secondv,
newframes, newcorners, newnormals, divDepth+1, depthLimit);
delete q3surf;
bu_free(newframes, "free subsurface frames array");
bu_free(newcorners, "free subsurface corners array");
@@ -1201,7 +1201,7 @@
//ON_BoundingBox bbox = q0surf->BoundingBox();
//bu_log("%d - in bbq0 rpp %f %f %f %f %f %f\n", divDepth,
bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[0] = subdivideSurfaceByKnots(east, firstu, v, newframes,
newcorners, newnormals, divDepth+1);
+ quads[0] = subdivideSurfaceByKnots(east, firstu, v, newframes,
newcorners, newnormals, divDepth+1, depthLimit);
delete east;
newframes[0] = sharedframes[0];
@@ -1223,7 +1223,7 @@
//bbox = q1surf->BoundingBox();
//bu_log("%d - in bbq1 rpp %f %f %f %f %f %f\n", divDepth,
bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[1] = subdivideSurfaceByKnots(west, secondu, v, newframes,
newcorners, newnormals, divDepth+1);
+ quads[1] = subdivideSurfaceByKnots(west, secondu, v, newframes,
newcorners, newnormals, divDepth+1, depthLimit);
delete west;
bu_free(newframes, "free subsurface frames array");
@@ -1365,7 +1365,7 @@
newnormals[4] = newframes[4].zaxis;
//ON_BoundingBox bbox = q0surf->BoundingBox();
//bu_log("%d - in bbq0 rpp %f %f %f %f %f %f\n", divDepth,
bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[0] = subdivideSurfaceByKnots(south, u, firstv, newframes,
newcorners, newnormals, divDepth+1);
+ quads[0] = subdivideSurfaceByKnots(south, u, firstv, newframes,
newcorners, newnormals, divDepth+1, depthLimit);
delete south;
newframes[0] = sharedframes[0];
@@ -1386,7 +1386,7 @@
newnormals[4] = newframes[4].zaxis;
//bbox = q1surf->BoundingBox();
//bu_log("%d - in bbq1 rpp %f %f %f %f %f %f\n", divDepth,
bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[1] = subdivideSurfaceByKnots(north, u, secondv,
newframes, newcorners, newnormals, divDepth+1);
+ quads[1] = subdivideSurfaceByKnots(north, u, secondv,
newframes, newcorners, newnormals, divDepth+1, depthLimit);
delete north;
bu_free(newframes, "free subsurface frames array");
@@ -1417,7 +1417,7 @@
} else {
//return surfaceBBox(localsurf, true, corners, normals, u, v);
//parent->addChild(subdivideSurface(localsurf, u, v, frames,
corners, normals,0));
- return subdivideSurface(localsurf, u, v, frames, corners,
normals,0);
+ return subdivideSurface(localsurf, u, v, frames, corners,
normals,0, depthLimit);
}
delete [] spanu;
delete [] spanv;
@@ -1434,7 +1434,8 @@
ON_Plane frames[],
ON_3dPoint corners[],
ON_3dVector normals[],
- int divDepth)
+ int divDepth,
+ int depthLimit)
{
const ON_Surface* surf = m_face->SurfaceOf();
ON_Interval usurf = surf->Domain(0);
@@ -1468,7 +1469,7 @@
double ratio = 5.0;
localsurf->GetSurfaceSize(&width, &height);
if (((width/height < ratio) && (width/height > 1.0/ratio))
- && (isFlat(localsurf, frames, normals,
corners, u, v)) || (divDepth >= BREP_MAX_FT_DEPTH)) { //BREP_MAX_FT_DEPTH))) {
+ && (isFlat(localsurf, frames, normals,
corners, u, v)) || (divDepth >= depthLimit)) { //BREP_MAX_FT_DEPTH))) {
return surfaceBBox(localsurf, true, corners, normals, u, v);
} else {
fastf_t uflat = isFlatU(localsurf, frames, normals, corners, u,
v);
@@ -1602,7 +1603,7 @@
newframes[4] = frames[5];
newcorners[4] = corners[5];
newnormals[4] = normals[5];
- quads[0] = subdivideSurface(q0surf,
u.ParameterAt(first), v.ParameterAt(first), newframes, newcorners, newnormals,
divDepth+1);
+ quads[0] = subdivideSurface(q0surf,
u.ParameterAt(first), v.ParameterAt(first), newframes, newcorners, newnormals,
divDepth+1, depthLimit);
delete q0surf;
newframes[0] = sharedframes[0];
newcorners[0] = sharedcorners[0];
@@ -1619,7 +1620,7 @@
newframes[4] = frames[7];
newcorners[4] = corners[7];
newnormals[4] = normals[7];
- quads[1] = subdivideSurface(q1surf,
u.ParameterAt(second), v.ParameterAt(first), newframes, newcorners, newnormals,
divDepth+1);
+ quads[1] = subdivideSurface(q1surf,
u.ParameterAt(second), v.ParameterAt(first), newframes, newcorners, newnormals,
divDepth+1, depthLimit);
delete q1surf;
newframes[0] = frames[4];
newcorners[0] = corners[4];
@@ -1636,7 +1637,7 @@
newframes[4] = frames[8];
newcorners[4] = corners[8];
newnormals[4] = normals[8];
- quads[2] = subdivideSurface(q2surf,
u.ParameterAt(second), v.ParameterAt(second), newframes, newcorners,
newnormals, divDepth+1);
+ quads[2] = subdivideSurface(q2surf,
u.ParameterAt(second), v.ParameterAt(second), newframes, newcorners,
newnormals, divDepth+1, depthLimit);
delete q2surf;
newframes[0] = sharedframes[1];
newcorners[0] = sharedcorners[1];
@@ -1653,7 +1654,7 @@
newframes[4] = frames[6];
newcorners[4] = corners[6];
newnormals[4] = normals[6];
- quads[3] = subdivideSurface(q3surf,
u.ParameterAt(first), v.ParameterAt(second), newframes, newcorners, newnormals,
divDepth+1);
+ quads[3] = subdivideSurface(q3surf,
u.ParameterAt(first), v.ParameterAt(second), newframes, newcorners, newnormals,
divDepth+1, depthLimit);
delete q3surf;
bu_free(newframes, "free subsurface frames array");
bu_free(newcorners, "free subsurface corners array");
@@ -1807,8 +1808,7 @@
newnormals[4] = newframes[4].zaxis;
//ON_BoundingBox bbox = q0surf->BoundingBox();
//bu_log("%d - in bbq0 rpp %f %f %f %f %f %f\n",
divDepth, bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[0] = subdivideSurface(east, u.ParameterAt(first),
- v, newframes, newcorners, newnormals,
divDepth + 1);
+ quads[0] = subdivideSurface(east, u.ParameterAt(first),
v, newframes, newcorners, newnormals, divDepth + 1, depthLimit);
delete east;
newframes[0] = sharedframes[0];
@@ -1829,8 +1829,7 @@
newnormals[4] = newframes[4].zaxis;
//bbox = q1surf->BoundingBox();
//bu_log("%d - in bbq1 rpp %f %f %f %f %f %f\n",
divDepth, bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[1] = subdivideSurface(west, u.ParameterAt(second),
- v, newframes, newcorners, newnormals,
divDepth + 1);
+ quads[1] = subdivideSurface(west,
u.ParameterAt(second), v, newframes, newcorners, newnormals, divDepth + 1,
depthLimit);
delete west;
bu_free(newframes, "free subsurface frames array");
@@ -1968,8 +1967,7 @@
newnormals[4] = newframes[4].zaxis;
//ON_BoundingBox bbox = q0surf->BoundingBox();
//bu_log("%d - in bbq0 rpp %f %f %f %f %f %f\n",
divDepth, bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[0] = subdivideSurface(south, u,
- v.ParameterAt(first), newframes,
newcorners, newnormals, divDepth + 1);
+ quads[0] = subdivideSurface(south, u,
v.ParameterAt(first), newframes, newcorners, newnormals, divDepth + 1,
depthLimit);
delete south;
newframes[0] = sharedframes[0];
@@ -1990,8 +1988,7 @@
newnormals[4] = newframes[4].zaxis;
//bbox = q1surf->BoundingBox();
//bu_log("%d - in bbq1 rpp %f %f %f %f %f %f\n",
divDepth, bbox.m_min.x, bbox.m_max.x, bbox.m_min.y, bbox.m_max.y, bbox.m_min.z,
bbox.m_max.z);
- quads[1] = subdivideSurface(north, u,
- v.ParameterAt(second), newframes,
newcorners, newnormals, divDepth + 1);
+ quads[1] = subdivideSurface(north, u,
v.ParameterAt(second), newframes, newcorners, newnormals, divDepth + 1,
depthLimit);
delete north;
bu_free(newframes, "free subsurface frames array");
Modified: brlcad/trunk/src/librt/primitives/brep/brep.cpp
===================================================================
--- brlcad/trunk/src/librt/primitives/brep/brep.cpp 2010-12-07 14:00:50 UTC
(rev 41532)
+++ brlcad/trunk/src/librt/primitives/brep/brep.cpp 2010-12-07 15:43:14 UTC
(rev 41533)
@@ -2310,7 +2310,363 @@
}
}
+/* a binary predicate for std:list implemented as a function */
+bool near_equal(double first, double second) {
+ struct bn_tol tol;
+ struct bn_tol *ptr_tol;
+ tol.magic = BN_TOL_MAGIC;
+ tol.dist = 1e-6;
+ tol.dist_sq = tol.dist * tol.dist;
+ tol.perp = 1e-6;
+ tol.para = 1 - tol.perp;
+
+ ptr_tol = &tol;
+ return BN_APPROXEQUAL(first, second, ptr_tol);
+}
+void plot_sum_surface(struct bu_list *vhead, const ON_Surface *surf,
+ int isocurveres, int gridres) {
+ double pt1[3], pt2[3];
+ ON_2dPoint from, to;
+
+ ON_Interval udom = surf->Domain(0);
+ ON_Interval vdom = surf->Domain(1);
+
+ for (int u = 0; u <= gridres; u++) {
+ for (int v = 1; v <= isocurveres; v++) {
+ ON_3dPoint p = surf->PointAt(udom.ParameterAt((double) u
+ / (double) gridres),
vdom.ParameterAt((double) (v - 1)
+ / (double) isocurveres));
+ VMOVE(pt1, p);
+ p = surf->PointAt(udom.ParameterAt((double) u /
(double) gridres),
+ vdom.ParameterAt((double) v / (double)
isocurveres));
+ VMOVE(pt2, p);
+ RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
+ }
+ }
+
+ for (int v = 0; v <= gridres; v++) {
+ for (int u = 1; u <= isocurveres; u++) {
+ ON_3dPoint p = surf->PointAt(udom.ParameterAt((double)
(u - 1)
+ / (double) isocurveres),
vdom.ParameterAt((double) v
+ / (double) gridres));
+ VMOVE(pt1, p);
+ p = surf->PointAt(udom.ParameterAt((double) u
+ / (double) isocurveres),
vdom.ParameterAt((double) v
+ / (double) gridres));
+ VMOVE(pt2, p);
+ RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
+ }
+ }
+ return;
+}
+void plotisoUCheckForTrim(struct bu_list *vhead, SurfaceTree* st, fastf_t from,
+ fastf_t to, fastf_t v) {
+ double pt1[3], pt2[3];
+ std::list<BRNode*> m_trims_right;
+ std::list<double> trim_hits;
+
+ const ON_Surface *surf = st->getSurface();
+ CurveTree *ctree = st->ctree;
+ double umin, umax;
+ surf->GetDomain(0, &umin, &umax);
+
+ m_trims_right.clear();
+
+ fastf_t tol = 0.001;
+ ON_2dPoint pt;
+ pt.x = umin;
+ pt.y = v;
+
+ if (ctree != NULL) {
+ m_trims_right.clear();
+ ctree->getLeavesRight(m_trims_right, pt, tol);
+ }
+
+ int cnt = 1;
+ //bu_log("V - %f\n",pt.x);
+ trim_hits.clear();
+ for (std::list<BRNode*>::iterator i = m_trims_right.begin(); i
+ != m_trims_right.end(); i++, cnt++) {
+ BRNode* br = dynamic_cast<BRNode*> (*i);
+
+ point_t bmin, bmax;
+ if (!br->m_Horizontal) {
+ br->GetBBox(bmin, bmax);
+ if (((bmin[Y] - tol) <= pt[Y]) && (pt[Y] <= (bmax[Y] +
tol))) { //if check trim and in BBox
+ fastf_t u = br->getCurveEstimateOfU(pt[Y], tol);
+ trim_hits.push_back(u);
+ //bu_log("%d U %d - %f pt %f,%f bmin %f,%f
bmax
%f,%f\n",br->m_face->m_face_index,cnt,u,pt.x,pt.y,bmin[X],bmin[Y],bmax[X],bmax[Y]);
+ }
+ }
+ }
+ trim_hits.sort();
+ trim_hits.unique(near_equal);
+
+ int hit_cnt = trim_hits.size();
+ cnt = 1;
+ //bu_log("\tplotisoUCheckForTrim: hit_cnt %d from center %f %f 0.0 to
center %f %f 0.0\n",hit_cnt,from,v ,to,v);
+
+ if ((hit_cnt > 0) && ((hit_cnt % 2) == 0)) {
+ while (!trim_hits.empty()) {
+ double start = trim_hits.front();
+ if (start < from) {
+ start = from;
+ }
+ trim_hits.pop_front();
+ double end = trim_hits.front();
+ if (end > to) {
+ end = to;
+ }
+ trim_hits.pop_front();
+ //bu_log("\tfrom - %f, to - %f\n",from,to);
+ fastf_t deltax = (end - start) / 50.0;
+ if (deltax > 0.001) {
+ for (fastf_t x = start; x < end; x = x +
deltax) {
+ ON_3dPoint p = surf->PointAt(x, pt.y);
+ VMOVE(pt1, p);
+ if (x + deltax > end) {
+ p = surf->PointAt(end, pt.y);
+ } else {
+ p = surf->PointAt(x + deltax,
pt.y);
+ }
+ VMOVE(pt2, p);
+
+ // bu_log(
+ //
"\t\t%d from center %f %f 0.0 to center %f %f 0.0\n",
+ //
cnt++, x, v, x + deltax, v);
+
+ RT_ADD_VLIST(vhead, pt1,
BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2,
BN_VLIST_LINE_DRAW);
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+void plotisoVCheckForTrim(struct bu_list *vhead, SurfaceTree* st, fastf_t from,
+ fastf_t to, fastf_t u) {
+ double pt1[3], pt2[3];
+ std::list<BRNode*> m_trims_above;
+ std::list<double> trim_hits;
+
+ const ON_Surface *surf = st->getSurface();
+ CurveTree *ctree = st->ctree;
+ double vmin, vmax;
+ surf->GetDomain(1, &vmin, &vmax);
+
+ m_trims_above.clear();
+
+ fastf_t tol = 0.001;
+ ON_2dPoint pt;
+ pt.x = u;
+ pt.y = vmin;
+
+ if (ctree != NULL) {
+ m_trims_above.clear();
+ ctree->getLeavesAbove(m_trims_above, pt, tol);
+ }
+
+ int cnt = 1;
+ trim_hits.clear();
+ for (std::list<BRNode*>::iterator i = m_trims_above.begin(); i
+ != m_trims_above.end(); i++, cnt++) {
+ BRNode* br = dynamic_cast<BRNode*> (*i);
+
+ point_t bmin, bmax;
+ if (!br->m_Vertical) {
+ br->GetBBox(bmin, bmax);
+
+ if (((bmin[X] - tol) <= pt[X]) && (pt[X] <= (bmax[X] +
tol))) { //if check trim and in BBox
+ fastf_t v = br->getCurveEstimateOfV(pt[X], tol);
+ trim_hits.push_back(v);
+ //bu_log("%d V %d - %f pt %f,%f bmin %f,%f
bmax
%f,%f\n",br->m_face->m_face_index,cnt,v,pt.x,pt.y,bmin[X],bmin[Y],bmax[X],bmax[Y]);
+ }
+ }
+ }
+ trim_hits.sort();
+ trim_hits.unique(near_equal);
+
+ size_t hit_cnt = trim_hits.size();
+ cnt = 1;
+
+ //bu_log("\tplotisoVCheckForTrim: hit_cnt %d from center %f %f 0.0 to
center %f %f 0.0\n",hit_cnt,u,from,u,to);
+
+ if ((hit_cnt > 0) && ((hit_cnt % 2) == 0)) {
+ while (!trim_hits.empty()) {
+ double start = trim_hits.front();
+ trim_hits.pop_front();
+ if (start < from) {
+ start = from;
+ }
+ double end = trim_hits.front();
+ trim_hits.pop_front();
+ if (end > to) {
+ end = to;
+ }
+ //bu_log("\tfrom - %f, to - %f\n",from,to);
+ fastf_t deltay = (end - start) / 50.0;
+ if (deltay > 0.001) {
+ for (fastf_t y = start; y < end; y = y +
deltay) {
+ ON_3dPoint p = surf->PointAt(pt.x, y);
+ VMOVE(pt1, p);
+ if (y + deltay > end) {
+ p = surf->PointAt(pt.x, end);
+ } else {
+ p = surf->PointAt(pt.x, y +
deltay);
+ }
+ VMOVE(pt2, p);
+
+ //bu_log("\t\t%d from center %f %f 0.0
to center %f %f 0.0\n",
+ // cnt++, u, y, u, y +
deltay);
+
+ RT_ADD_VLIST(vhead, pt1,
BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2,
BN_VLIST_LINE_DRAW);
+ }
+ }
+ }
+ }
+ return;
+}
+
+void plotisoU(struct bu_list *vhead, SurfaceTree* st, fastf_t from, fastf_t to,
+ fastf_t v, int curveres) {
+ double pt1[3], pt2[3];
+ fastf_t deltau = (to - from) / curveres;
+ const ON_Surface *surf = st->getSurface();
+
+ for (fastf_t u = from; u < to; u = u + deltau) {
+ ON_3dPoint p = surf->PointAt(u, v);
+ //bu_log("p1 2d - %f,%f 3d - %f,%f,%f\n",pt.x, y,p.x,p.y,p.z);
+ VMOVE(pt1, p);
+ if (u + deltau > to) {
+ p = surf->PointAt(to, v);
+ } else {
+ p = surf->PointAt(u + deltau, v);
+ }
+ //bu_log("p1 2d - %f,%f 3d -
%f,%f,%f\n",pt.x,y+deltay,p.x,p.y,p.z);
+ VMOVE(pt2, p);
+ RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
+ }
+}
+
+void plotisoV(struct bu_list *vhead, SurfaceTree* st, fastf_t from, fastf_t to,
+ fastf_t u, int curveres) {
+ double pt1[3], pt2[3];
+ fastf_t deltav = (to - from) / curveres;
+ const ON_Surface *surf = st->getSurface();
+
+ for (fastf_t v = from; v < to; v = v + deltav) {
+ ON_3dPoint p = surf->PointAt(u, v);
+ //bu_log("p1 2d - %f,%f 3d - %f,%f,%f\n",pt.x, y,p.x,p.y,p.z);
+ VMOVE(pt1, p);
+ if (v + deltav > to) {
+ p = surf->PointAt(u, to);
+ } else {
+ p = surf->PointAt(u, v + deltav);
+ }
+ //bu_log("p1 2d - %f,%f 3d -
%f,%f,%f\n",pt.x,y+deltay,p.x,p.y,p.z);
+ VMOVE(pt2, p);
+ RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
+ }
+}
+
+void plot_BBNode(struct bu_list *vhead, SurfaceTree* st, BBNode * node, int
isocurveres, int gridres) {
+ if (node->isLeaf()) {
+ //draw leaf
+ if (node->m_trimmed) {
+ return; // nothing to do node is trimmed
+ } else if (node->m_checkTrim) { // node may contain trim check
all corners
+ fastf_t u = node->m_u[0];
+ fastf_t v = node->m_v[0];
+ fastf_t from = u;
+ fastf_t to = node->m_u[1];
+ //bu_log("drawBBNode: node %x uvmin center %f %f 0.0,
uvmax center %f %f
0.0\n",node,node->m_u[0],node->m_v[0],node->m_u[1],node->m_v[1]);
+
+ plotisoUCheckForTrim(vhead, st, from, to, v); //bottom
+ v = node->m_v[1];
+ plotisoUCheckForTrim(vhead, st, from, to, v); //top
+ from = node->m_v[0];
+ to = node->m_v[1];
+ plotisoVCheckForTrim(vhead, st, from, to, u); //left
+ u = node->m_u[1];
+ plotisoVCheckForTrim(vhead, st, from, to, u); //right
+ return;
+ } else { // fully untrimmed just draw bottom and right edges
+ fastf_t u = node->m_u[0];
+ fastf_t v = node->m_v[0];
+ fastf_t from = u;
+ fastf_t to = node->m_u[1];
+ plotisoU(vhead, st, from, to, v, isocurveres); //bottom
+
+ from = v;
+ to = node->m_v[1];
+ plotisoV(vhead, st, from, to, u, isocurveres); //right
+ return;
+ }
+ } else {
+ if (node->m_children.size() > 0) {
+ for (std::vector<BBNode*>::iterator childnode =
+ node->m_children.begin(); childnode
+ != node->m_children.end(); childnode++)
{
+ plot_BBNode(vhead, st,
*childnode,isocurveres,gridres);
+ }
+ }
+ }
+}
+
+void plot_face_from_surface_tree(struct bu_list *vhead, SurfaceTree* st,
+ int isocurveres, int gridres) {
+ BBNode *root = st->getRootNode();
+ plot_BBNode(vhead, st, root, isocurveres, gridres);
+}
+///////////////////////////
+void plot_face_trim(struct bu_list *vhead, ON_BrepFace &face, int plotres,
+ bool dim3d) {
+ const ON_Surface* surf = face.SurfaceOf();
+ double umin, umax;
+ double pt1[3], pt2[3];
+ ON_2dPoint from, to;
+
+ ON_TextLog tl(stderr);
+
+ surf->GetDomain(0, &umin, &umax);
+ for (int i = 0; i < face.LoopCount(); i++) {
+ ON_BrepLoop* loop = face.Loop(i);
+ // for each trim
+ for (int j = 0; j < loop->m_ti.Count(); j++) {
+ ON_BrepTrim& trim = face.Brep()->m_T[loop->m_ti[j]];
+ const ON_Curve* trimCurve = trim.TrimCurveOf();
+ //trimCurve->Dump(tl);
+
+ ON_Interval dom = trimCurve->Domain();
+ // XXX todo: dynamically sample the curve
+ for (int k = 1; k <= plotres; k++) {
+ ON_3dPoint p =
trimCurve->PointAt(dom.ParameterAt((double) (k
+ - 1) / (double) plotres));
+ if (dim3d)
+ p = surf->PointAt(p.x, p.y);
+ VMOVE(pt1, p);
+ p = trimCurve->PointAt(dom.ParameterAt((double)
k
+ / (double) plotres));
+ if (dim3d)
+ p = surf->PointAt(p.x, p.y);
+ VMOVE(pt2, p);
+ RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
+ }
+ }
+ }
+
+ return;
+}
+
/**
* R T _ B R E P _ P L O T
*
@@ -2340,177 +2696,89 @@
bi = (struct rt_brep_internal*)ip->idb_ptr;
RT_BREP_CK_MAGIC(bi);
- /* XXX below does NOT work for non-trivial faces, in addition to
- * the fact that openNURBS does NOT support meshes!
- *
- * XXX currently not handling the tolerances.
- *
- * ON_MeshParameters mp;
- * mp.JaggedAndFasterMeshParameters();
- *
- * ON_SimpleArray<ON_Mesh*> mesh_list;
- * bi->brep->CreateMesh(mp, mesh_list);
- *
- * point_t pt1, pt2;
- * ON_SimpleArray<ON_2dex> edges;
- * for (int i = 0; i < mesh_list.Count(); i++) {
- * const ON_Mesh* mesh = mesh_list[i];
- * mesh->GetMeshEdges(edges);
- * for (int j = 0; j < edges.Count(); j++) {
- * ON_MeshVertexRef v1 = mesh->VertexRef(edges[j].i);
- * ON_MeshVertexRef v2 = mesh->VertexRef(edges[j].j);
- * VSET(pt1, v1.Point().x, v1.Point().y, v1.Point().z);
- * VSET(pt2, v2.Point().x, v2.Point().y, v2.Point().z);
- * RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
- * RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
- * }
- * edges.Empty();
- * }
- *
- * So we'll do it by hand by grabbing each topological edge from
- * the brep and rendering it that way...
- */
ON_Brep* brep = bi->brep;
+ int gridres = 10;
+ int isocurveres = 100;
- point_t pt1, pt2;
+ for (int index = 0; index < brep->m_F.Count(); index++) {
+ ON_BrepFace& face = brep->m_F[index];
+ const ON_Surface *surf = face.SurfaceOf();
- for (i = 0; i < bi->brep->m_E.Count(); i++) {
- ON_BrepEdge& e = brep->m_E[i];
- const ON_Curve* crv = e.EdgeCurveOf();
+ ON_RevSurface *revsurf;
+ ON_SumSurface *sumsurf;
+ if ((surf->IsClosed(0) || surf->IsClosed(1)) && (sumsurf =
const_cast<ON_SumSurface *> (ON_SumSurface::Cast(surf)))) {
+ SurfaceTree* st = new SurfaceTree(&face, true, 2);
- if (crv->IsLinear()) {
- ON_BrepVertex& v1 = brep->m_V[e.m_vi[0]];
- ON_BrepVertex& v2 = brep->m_V[e.m_vi[1]];
- VMOVE(pt1, v1.Point());
- VMOVE(pt2, v2.Point());
- RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
- RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
- } else {
- ON_Interval dom = crv->Domain();
+ plot_face_from_surface_tree(vhead, st, isocurveres,
gridres);
- double domainval = 0.0;
- double olddomainval = 1.0;
- int crudestep = 0;
- // Insert first point.
- ON_3dPoint p = crv->PointAt(dom.ParameterAt(domainval));
- VMOVE(pt1, p);
- RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
+ delete st;
+ } else if (surf->IsClosed(0) || surf->IsClosed(1) || (revsurf
+ = const_cast<ON_RevSurface *>
(ON_RevSurface::Cast(surf)))) {
- /* Dynamic sampling approach - start with an initial guess
- * for the next point of one tenth of the domain length
- * further down the domain from the previous value. Set a
- * maximum physical distance between points of 100 times
- * the model tolerance. Reduce the increment until the
- * tolerance is satisfied, then add the point and use it
- * as the starting point for the next calculation until
- * the whole domain is finished. Perhaps it would be more
- * ideal to base the tolerance on some fraction of the
- * curve bounding box dimensions?
- */
+ SurfaceTree* st = new SurfaceTree(&face, true, 0);
- while (domainval < 1.0 && crudestep <= 100) {
- olddomainval = domainval;
- if (crudestep == 0) domainval = find_next_point(crv, domainval,
0.1, tol->dist*100, 0);
- if (crudestep >= 1 || NEAR_ZERO(domainval, SMALL_FASTF)) {
- crudestep++;
- domainval = olddomainval + (1.0 -
olddomainval)/100*crudestep;
+ plot_face_from_surface_tree(vhead, st, isocurveres,
gridres);
+
+ delete st;
}
- p = crv->PointAt(dom.ParameterAt(domainval));
- VMOVE(pt1, p);
- RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_DRAW);
- }
}
- }
+ {
-/*
- * DEBUGGING WIREFRAMES
- */
+ point_t pt1, pt2;
-// Routine to draw the bounding boxes in the surface
-// tree.
-//
-// for (int i = 0; i < brep->m_F.Count(); i++) {
-// ON_BrepFace& f = brep->m_F[i];
-// SurfaceTree st(&f);
-// plot_bbnode(st.getRootNode(), vhead, 0, 1, 8);
-// }
+ for (i = 0; i < bi->brep->m_E.Count(); i++) {
+ ON_BrepEdge& e = brep->m_E[i];
+ const ON_Curve* crv = e.EdgeCurveOf();
+ if (crv->IsLinear()) {
+ ON_BrepVertex& v1 = brep->m_V[e.m_vi[0]];
+ ON_BrepVertex& v2 = brep->m_V[e.m_vi[1]];
+ VMOVE(pt1, v1.Point());
+ VMOVE(pt2, v2.Point());
+ RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
+ RT_ADD_VLIST(vhead, pt2, BN_VLIST_LINE_DRAW);
+ } else {
+ ON_Interval dom = crv->Domain();
- /* Routine to iterate over the surfaces in the BREP and plot lines
- * corresponding to their projections into 3-space. Very crude
- * walk method - doesn't properly handle drawing in the case of
- * trims - but it illustrates how to go straight from uv parameter
- * space to real space coordinates. Needs to become proper
- * tesselation routine.
- */
+ double domainval = 0.0;
+ double olddomainval = 1.0;
+ int crudestep = 0;
+ // Insert first point.
+ ON_3dPoint p =
crv->PointAt(dom.ParameterAt(domainval));
+ VMOVE(pt1, p);
+ RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
-/* for (i = 0; i < bi->brep->m_F.Count(); i++) {
- ON_BrepFace *f = &(bi->brep->m_F[i]);
- const ON_Surface *s = bi->brep->m_F[i].SurfaceOf();
- int foundfirst = 0;
- for (j = 0; j <= 20; j++) {
- for (k = 0; k <= 20; k++) {
- ON_2dPoint uv;
- ON_3dPoint plotpt;
- uv.x = s->Domain(0).ParameterAt((double)j/20);
- uv.y = s->Domain(1).ParameterAt((double)k/20);
- s->EvPoint(uv.x, uv.y, plotpt, 0, 0);
- VMOVE(pt1, plotpt);
- if (j == 0 || foundfirst == 0) {
- RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
- foundfirst = 1;
- } else {
- RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_DRAW);
- }
- }
- }
- }*/
+ /* Dynamic sampling approach - start with an
initial guess
+ * for the next point of one tenth of the
domain length
+ * further down the domain from the previous
value. Set a
+ * maximum physical distance between points of
100 times
+ * the model tolerance. Reduce the increment
until the
+ * tolerance is satisfied, then add the point
and use it
+ * as the starting point for the next
calculation until
+ * the whole domain is finished. Perhaps it
would be more
+ * ideal to base the tolerance on some fraction
of the
+ * curve bounding box dimensions?
+ */
+ while (domainval < 1.0 && crudestep <= 100) {
+ olddomainval = domainval;
+ if (crudestep == 0)
+ domainval =
find_next_point(crv, domainval, 0.1,
+ tol->dist *
100, 0);
+ if (crudestep >= 1 ||
NEAR_ZERO(domainval, SMALL_FASTF)) {
+ crudestep++;
+ domainval = olddomainval + (1.0
- olddomainval)
+ / 100 *
crudestep;
+ }
+ p =
crv->PointAt(dom.ParameterAt(domainval));
+ VMOVE(pt1, p);
+ RT_ADD_VLIST(vhead, pt1,
BN_VLIST_LINE_DRAW);
+ }
+ }
+ }
+ }
- /* Routine to iterate over the surfaces in the BREP and plot lines
- * corresponding to the trimming curve positions in 3-space.
- * Normally, this will correspond pretty well to edges, but will
- * show some cases where two surfaces are intended to join without
- * an edge
- */
- /*
- for (i = 0; i < bi->brep->m_F.Count(); i++) {
- ON_BrepFace *f = &(bi->brep->m_F[i]);
- const ON_Surface *s = bi->brep->m_F[i].SurfaceOf();
- for (j = 0; j < f->LoopCount(); j++) {
- ON_BrepLoop* loop = f->Loop(j);
- int foundfirst = 0;
- for (int k = 0; k < loop->m_ti.Count(); k++) {
- ON_BrepTrim& trim = f->Brep()->m_T[loop->m_ti[k]];
- const ON_Curve* trimCurve = trim.TrimCurveOf();
- ON_Interval dom = trimCurve->Domain();
- double domainval = 0.0;
- double olddomainval = 1.0;
- int crudestep = 0;
- ON_3dPoint trimpoint2d = trimCurve->PointAt(dom.ParameterAt(domainval));
- ON_3dPoint trimpoint3d;
- s->EvPoint(trimpoint2d[0], trimpoint2d[1], trimpoint3d, 0, 0);
- VMOVE(pt1, trimpoint3d);
- RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_MOVE);
- while (domainval < 1.0 && crudestep <= 100) {
- olddomainval = domainval;
- if (crudestep == 0) domainval = find_next_trimming_point(trimCurve, s,
domainval, 0.1, tol->dist*100, 0);
- if (crudestep >= 1 || domainval == 0.0) {
- crudestep++;
- domainval = olddomainval + (1.0 - olddomainval)/100*crudestep;
- }
- trimpoint2d = trimCurve->PointAt(dom.ParameterAt(domainval));
- s->EvPoint(trimpoint2d[0], trimpoint2d[1], trimpoint3d, 0, 0);
- VMOVE(pt1, trimpoint3d);
- RT_ADD_VLIST(vhead, pt1, BN_VLIST_LINE_DRAW);
- }
- }
- }
- }
- */
-
-
return 0;
}
Modified: brlcad/trunk/src/librt/primitives/brep/brep_debug.cpp
===================================================================
--- brlcad/trunk/src/librt/primitives/brep/brep_debug.cpp 2010-12-07
14:00:50 UTC (rev 41532)
+++ brlcad/trunk/src/librt/primitives/brep/brep_debug.cpp 2010-12-07
15:43:14 UTC (rev 41533)
@@ -1115,21 +1115,8 @@
}
/* a binary predicate for std:list implemented as a function */
-bool near_equal (double first, double second)
-{
- struct bn_tol tol;
- struct bn_tol *ptr_tol;
+extern bool near_equal (double first, double second);
- tol.magic = BN_TOL_MAGIC;
- tol.dist = 1e-6;
- tol.dist_sq = tol.dist * tol.dist;
- tol.perp = 1e-6;
- tol.para = 1 - tol.perp;
-
- ptr_tol = &tol;
- return BN_APPROXEQUAL(first,second,ptr_tol);
-}
-
void
plotFace(SurfaceTree* st, struct bn_vlblock *vbp, int isocurveres, int gridres)
{
@@ -1634,10 +1621,11 @@
if (index == -1) {
for (index = 0; index < brep->m_F.Count(); index++) {
ON_BrepFace& face = brep->m_F[index];
- SurfaceTree* st = new SurfaceTree(&face);
+ SurfaceTree* st = new SurfaceTree(&face, true, 0);
#if 0
plotFace(st, vbp, plotres, plotres);
#else
+ plottrim(face, vbp, plotres, true);
plotFaceFromSurfaceTree(st,vbp,plotres,plotres);
#endif
delete st;
@@ -1646,10 +1634,11 @@
ON_BrepFaceArray& faces = brep->m_F;
if (index < faces.Count()) {
ON_BrepFace& face = faces[index];
- SurfaceTree* st = new SurfaceTree(&face);
+ SurfaceTree* st = new SurfaceTree(&face, true, 0);
#if 0
plotFace(st, vbp, plotres, plotres);
#else
+ plottrim(face, vbp, plotres, true);
plotFaceFromSurfaceTree(st,vbp,plotres,plotres);
#endif
delete st;
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
What happens now with your Lotus Notes apps - do you make another costly
upgrade, or settle for being marooned without product support? Time to move
off Lotus Notes and onto the cloud with Force.com, apps are easier to build,
use, and manage than apps on traditional platforms. Sign up for the Lotus
Notes Migration Kit to learn more. http://p.sf.net/sfu/salesforce-d2d
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits