Revision: 55762
          http://sourceforge.net/p/brlcad/code/55762
Author:   starseeker
Date:     2013-06-13 19:11:14 +0000 (Thu, 13 Jun 2013)
Log Message:
-----------
Refactor some NURBS functionality from the tree methods into functions, and add 
doxygen comments.

Modified Paths:
--------------
    brlcad/trunk/src/libbrep/libbrep_brep_tools.cpp
    brlcad/trunk/src/libbrep/libbrep_brep_tools.h
    brlcad/trunk/src/libbrep/opennurbs_ext.cpp

Modified: brlcad/trunk/src/libbrep/libbrep_brep_tools.cpp
===================================================================
--- brlcad/trunk/src/libbrep/libbrep_brep_tools.cpp     2013-06-13 19:08:31 UTC 
(rev 55761)
+++ brlcad/trunk/src/libbrep/libbrep_brep_tools.cpp     2013-06-13 19:11:14 UTC 
(rev 55762)
@@ -27,8 +27,151 @@
 
 #include "opennurbs.h"
 
-// For any pre-existing surface passed as one of the t* args, this is a no-op
-void ON_Surface_Create_Scratch_Surfaces(
+bool ON_NearZero(double val, double epsilon) {
+    return (val > -epsilon) && (val < epsilon);
+}
+
+int ON_Curve_Has_Tangent(const ON_Curve* curve, double ct_min, double ct_max, 
double t_tol) {
+
+    bool tanx1, tanx2, x_changed;
+    bool tany1, tany2, y_changed;
+    bool slopex, slopey;
+    double xdelta, ydelta;
+    ON_3dVector tangent1, tangent2;
+    ON_3dPoint p1, p2;
+    ON_Interval t(ct_min, ct_max);
+
+    tangent1 = curve->TangentAt(t[0]);
+    tangent2 = curve->TangentAt(t[1]);
+
+    tanx1 = (tangent1[0] < 0.0);
+    tanx2 = (tangent2[0] < 0.0);
+    tany1 = (tangent1[1] < 0.0);
+    tany2 = (tangent2[1] < 0.0);
+
+    x_changed =(tanx1 != tanx2);
+    y_changed =(tany1 != tany2);
+
+    if (x_changed && y_changed) return 3; //horz & vert 
+    if (x_changed) return 1;//need to get vertical tangent
+    if (y_changed) return 2;//need to find horizontal tangent
+
+    p1 = curve->PointAt(t[0]);
+    p2 = curve->PointAt(t[1]);
+
+    xdelta = (p2[0] - p1[0]);
+    slopex = (xdelta < 0.0);
+    ydelta = (p2[1] - p1[1]);
+    slopey = (ydelta < 0.0);
+
+    // If we have no slope change
+    // in x or y, we have a tangent line
+    if (ON_NearZero(xdelta, t_tol) || ON_NearZero(ydelta, t_tol)) return 0;
+
+    if ((slopex != tanx1) || (slopey != tany1)) return 3;
+
+    return 0;
+}
+
+bool ON_Surface_IsFlat(ON_Plane *frames, double f_tol) 
+{
+    double Ndot=1.0;
+
+    for(int i=0; i<8; i++) {
+       for( int j=i+1; j<9; j++) {
+           if ((Ndot = Ndot * frames[i].zaxis * frames[j].zaxis) < f_tol) {
+               return false;
+           }
+       }
+    }
+
+    return true;
+}
+
+bool ON_Surface_IsFlat_U(ON_Plane *frames, double f_tol)
+{
+    // check surface normals in U direction
+    double Ndot = 1.0;
+    if ((Ndot=frames[0].zaxis * frames[1].zaxis) < f_tol) {
+       return false;
+    } else if ((Ndot=Ndot * frames[2].zaxis * frames[3].zaxis) < f_tol) {
+       return false;
+    } else if ((Ndot=Ndot * frames[5].zaxis * frames[7].zaxis) < f_tol) {
+       return false;
+    } else if ((Ndot=Ndot * frames[6].zaxis * frames[8].zaxis) < f_tol) {
+       return false;
+    }
+
+    // check for U twist within plane
+    double Xdot = 1.0;
+    if ((Xdot=frames[0].xaxis * frames[1].xaxis) < f_tol) {
+       return false;
+    } else if ((Xdot=Xdot * frames[2].xaxis * frames[3].xaxis) < f_tol) {
+       return false;
+    } else if ((Xdot=Xdot * frames[5].xaxis * frames[7].xaxis) < f_tol) {
+       return false;
+    } else if ((Xdot=Xdot * frames[6].xaxis * frames[8].xaxis) < f_tol) {
+       return false;
+    }
+
+    return true;
+}
+
+bool ON_Surface_IsFlat_V(ON_Plane *frames, double f_tol)
+{
+    // check surface normals in V direction
+    double Ndot = 1.0;
+    if ((Ndot=frames[0].zaxis * frames[3].zaxis) < f_tol) {
+       return false;
+    } else if ((Ndot=Ndot * frames[1].zaxis * frames[2].zaxis) < f_tol) {
+       return false;
+    } else if ((Ndot=Ndot * frames[5].zaxis * frames[6].zaxis) < f_tol) {
+       return false;
+    } else if ((Ndot=Ndot * frames[7].zaxis * frames[8].zaxis) < f_tol) {
+       return false;
+    }
+
+    // check for V twist within plane
+    double Xdot = 1.0;
+    if ((Xdot=frames[0].xaxis * frames[3].xaxis) < f_tol) {
+       return false;
+    } else if ((Xdot=Xdot * frames[1].xaxis * frames[2].xaxis) < f_tol) {
+       return false;
+    } else if ((Xdot=Xdot * frames[5].xaxis * frames[6].xaxis) < f_tol) {
+       return false;
+    } else if ((Xdot=Xdot * frames[7].xaxis * frames[8].xaxis) < f_tol) {
+       return false;
+    }
+
+    return true;
+}
+
+bool ON_Surface_IsStraight(ON_Plane *frames, double s_tol) 
+{
+    double Xdot=1.0;
+
+    for(int i=0; i<8; i++) {
+        for( int j=i+1; j<9; j++) {
+            if ((Xdot = Xdot * frames[0].xaxis * frames[1].xaxis) < s_tol) {
+                    return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+/**
+ \brief Create surfaces and store their pointers in the t* arguments.  
+
+ For any pre-existing surface passed as one of the t* args, this is a no-op.
+
+ @param t1 Pointer to pointer addressing first surface
+ @param t2 Pointer to pointer addressing second surface
+ @param t3 Pointer to pointer addressing third surface
+ @param t4 Pointer to pointer addressing fourth surface
+*/
+ void ON_Surface_Create_Scratch_Surfaces(
        ON_Surface **t1,
        ON_Surface **t2,
        ON_Surface **t3,

Modified: brlcad/trunk/src/libbrep/libbrep_brep_tools.h
===================================================================
--- brlcad/trunk/src/libbrep/libbrep_brep_tools.h       2013-06-13 19:08:31 UTC 
(rev 55761)
+++ brlcad/trunk/src/libbrep/libbrep_brep_tools.h       2013-06-13 19:11:14 UTC 
(rev 55762)
@@ -44,6 +44,140 @@
 #endif
 
 /**
+  \brief Return truthfully whether a value is within a specified epsilon 
distance from zero.
+
+
+  @param val value to be tested
+  @param epsilon distance from zero defining the interval to be treated as 
"near" zero for the test 
+
+  @return @c true if the value is within the near-zero interval specified by 
epsilon, @c false otherwise.
+*/
+NURBS_EXPORT
+bool ON_NearZero(double val, double epsilon);
+
+
+/**
+  \brief Test whether a curve interval contains one or more horizontal or 
vertical tangents
+
+  @param curve ON_Curve to be tested
+  @param ct_min minimum t parameter value of the curve interval to be tested
+  @param ct_max maximum t parameter value of the curve interval to be tested
+  @param t_tol tolerance used to decide when a curve is a line tangent to X or 
Y axis
+
+  @return @c 0 if there are no tangent points in the interval, @c 1 if there 
is a single vertical tangent,
+  @c 2 if there is a single horizontal tangent, and @c 3 if multiple tangents 
are present.
+*/
+NURBS_EXPORT
+int ON_Curve_Has_Tangent(const ON_Curve* curve, double ct_min, double ct_max, 
double t_tol);
+
+
+#if 0
+/*
+  \verbatim
+    3-------------------2
+    |                   |
+    |    6         8    |
+    |                   |
+   V|         4         |
+    |                   |
+    |    5         7    |
+    |                   |
+    0-------------------1
+              U
+  \endverbatim
+*/
+#endif
+
+/**
+  \brief Perform flatness test of surface
+
+  Determine whether a given surface is flat enough, i.e. it falls
+  beneath our simple flatness constraints. The flatness constraint in
+  this case is a sampling of normals across the surface such that the
+  product of their combined dot products is close to 1.
+  
+  @f[ \prod_{i=1}^{7} n_i \dot n_{i+1} = 1 @f] 
+  
+  This code is using a slightly different placement of the interior normal
+  tests as compared to <a 
href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.90.7500&rep=rep1&type=pdf";>Abert's</a>
 approach:
+  
+  \verbatim
+     +-------------------+
+     |                   |
+     |    +         +    |
+     |                   |
+   V |         +         |
+     |                   |
+     |    +         +    |
+     |                   |
+     +-------------------+
+               U
+  \endverbatim
+  
+  
+  The "+" indicates the normal sample.
+  
+  The frenet frames are stored in the frames arrays according
+  to the following index values:
+  
+  \verbatim
+     3-------------------2 
+     |                   |
+     |    6         8    |
+     |                   |
+   V |         4         |
+     |                   |
+     |    5         7    |
+     |                   |
+     0-------------------1
+               U
+  \endverbatim
+
+  @param frames Array of 9 frenet frames
+  @param f_tol Flatness tolerance - 0 always evaluates to flat, 1 would be a 
perfectly flat surface. Generally something in the range 0.8-0.9 should suffice 
in raytracing subdivision (per <a 
href="http://www.uni-koblenz.de/~cg/Diplomarbeiten/DA_Oliver_Abert.pdf";>Abert, 
2005</a>)
+*/
+NURBS_EXPORT
+bool ON_Surface_IsFlat(ON_Plane *frames, double f_tol);
+
+/**
+  \brief Perform flatness test of surface in U only
+
+  Array index conventions are the same as ::ON_Surface_IsFlat.
+
+  @param frames Array of 9 frenet frames
+  @param s_tol Straightness tolerance - 0 always evaluates to straight, 1 
requires perfect straightness
+*/
+NURBS_EXPORT
+bool ON_Surface_IsFlat_U(ON_Plane *frames, double f_tol);
+
+
+/**
+  \brief Perform flatness test of surface in V only
+
+  Array index conventions are the same as ::ON_Surface_IsFlat.
+
+  @param frames Array of 9 frenet frames
+  @param s_tol Straightness tolerance - 0 always evaluates to straight, 1 
requires perfect straightness
+*/
+NURBS_EXPORT
+bool ON_Surface_IsFlat_V(ON_Plane *frames, double f_tol);
+
+
+/**
+  \brief Perform straightness test of surface
+
+  The straightness test compares flatness criteria to running product of the 
tangent vector of
+  the frenet frame projected onto each other tangent in the frame set.  Array 
index conventions
+  are the same as ::ON_Surface_IsFlat.
+
+  @param frames Array of 9 frenet frames
+  @param s_tol Straightness tolerance - 0 always evaluates to straight, 1 
requires perfect straightness
+*/
+NURBS_EXPORT
+bool ON_Surface_IsStraight(ON_Plane *frames, double s_tol);
+
+
+/**
   \brief Create a surface based on a subset of a parent surface
 
   Create a NURBS surface that corresponds to a subset

Modified: brlcad/trunk/src/libbrep/opennurbs_ext.cpp
===================================================================
--- brlcad/trunk/src/libbrep/opennurbs_ext.cpp  2013-06-13 19:08:31 UTC (rev 
55761)
+++ brlcad/trunk/src/libbrep/opennurbs_ext.cpp  2013-06-13 19:11:14 UTC (rev 
55762)
@@ -36,6 +36,7 @@
 #include "bu.h"
 
 #include "brep.h"
+#include "libbrep_brep_tools.h"
 #include "dvec.h"
 
 #define RANGE_HI 0.55
@@ -53,12 +54,6 @@
 /// another arbitrary calculation tolerance (need to try VDIVIDE_TOL or 
VUNITIZE_TOL to tighten the bounds)
 #define TOL2 0.00001
 
-
-bool
-ON_NearZero(double x, double tolerance) {
-    return (x > -tolerance) && (x < tolerance);
-}
-
 void
 brep_get_plane_ray(ON_Ray& r, plane_ray& pr)
 {
@@ -462,81 +457,39 @@
 bool
 CurveTree::getHVTangents(const ON_Curve* curve, ON_Interval& t, 
std::list<fastf_t>& list)
 {
-    bool tanx1, tanx2, tanx_changed;
-    bool tany1, tany2, tany_changed;
-    bool tan_changed;
-    ON_3dVector tangent1, tangent2;
-    ON_3dPoint p1, p2;
+    double x;
+    double midpoint = (t[1]+t[0])/2.0;
+    ON_Interval left(t[0], midpoint);
+    ON_Interval right(midpoint, t[1]);
+    int status = ON_Curve_Has_Tangent(curve, t[0], t[1], TOL);
 
-    tangent1 = curve->TangentAt(t[0]);
-    tangent2 = curve->TangentAt(t[1]);
+    switch (status) {
 
-    tanx1 = (tangent1[X] < 0.0);
-    tanx2 = (tangent2[X] < 0.0);
-    tany1 = (tangent1[Y] < 0.0);
-    tany2 = (tangent2[Y] < 0.0);
+       case 1: /* 1 Vertical tangent */
+           x = getVerticalTangent(curve, t[0], t[1]);
+           list.push_back(x);
+           return true;
 
-    tanx_changed =(tanx1 != tanx2);
-    tany_changed =(tany1 != tany2);
+       case 2: /* 1 Horizontal tangent */
+           x = getHorizontalTangent(curve, t[0], t[1]);
+           list.push_back(x);
+           return true;
 
-    tan_changed = tanx_changed || tany_changed;
-
-    if (tan_changed) {
-       if (tanx_changed && tany_changed) {//horz & vert simply split
-           double midpoint = (t[1]+t[0])/2.0;
-           ON_Interval left(t[0], midpoint);
-           ON_Interval right(midpoint, t[1]);
+       case 3: /* Horizontal and vertical tangents present - Simple midpoint 
split */
            if (left.Length() > TOL)
                getHVTangents(curve, left, list);
            if (right.Length() > TOL)
                getHVTangents(curve, right, list);
            return true;
-       } else if (tanx_changed) {//find horz
-           double x = getVerticalTangent(curve, t[0], t[1]);
-           list.push_back(x);
-       } else { //find vert
-           double x = getHorizontalTangent(curve, t[0], t[1]);
-           list.push_back(x);
-       }
-    } else { // check point slope for change
-       bool slopex, slopex_changed;
-       bool slopey, slopey_changed;
-       bool slope_changed;
-       fastf_t xdelta, ydelta;
 
-       p1 = curve->PointAt(t[0]);
-       p2 = curve->PointAt(t[1]);
+       default:
+           return false;
 
-       xdelta = (p2[X] - p1[X]);
-       slopex = (xdelta < 0.0);
-       ydelta = (p2[Y] - p1[Y]);
-       slopey = (ydelta < 0.0);
+    }
 
-       if (NEAR_ZERO(xdelta, TOL) ||
-           NEAR_ZERO(ydelta, TOL)) {
-           return true;
-       }
-
-       slopex_changed = (slopex != tanx1);
-       slopey_changed = (slopey != tany1);
-
-       slope_changed = slopex_changed || slopey_changed;
-
-       if (slope_changed) {  //2 horz or 2 vert changes simply split
-           double midpoint = (t[1]+t[0])/2.0;
-           ON_Interval left(t[0], midpoint);
-           ON_Interval right(midpoint, t[1]);
-           if (left.Length() > TOL)
-               getHVTangents(curve, left, list);
-           if (right.Length() > TOL)
-               getHVTangents(curve, right, list);
-           return true;
-       }
-    }
-    return true;
+    return false;  //Should never get here
 }
 
-
 BRNode*
 CurveTree::curveBBox(const ON_Curve* curve, int adj_face_index, ON_Interval& 
t, bool isLeaf, bool innerTrim, const ON_BoundingBox& bb)
 {
@@ -2396,102 +2349,28 @@
 bool
 SurfaceTree::isFlat(ON_Plane *frames)
 {
-    double Ndot=1.0;
-
-    /* The flatness test compares flatness criteria to running product of the 
normal vector of
-     * the frenet frame projected onto each other normal in the frame set.
-     */
-    for(int i=0; i<8; i++) {
-       for( int j=i+1; j<9; j++) {
-           if ((Ndot = Ndot * frames[i].zaxis * frames[j].zaxis) < 
BREP_SURFACE_FLATNESS) {
-                   return false;
-           }
-       }
-    }
-
-    return true;
+    return ON_Surface_IsFlat(frames, BREP_SURFACE_FLATNESS);
 }
 
 
 bool
 SurfaceTree::isStraight(ON_Plane *frames)
 {
-    double Xdot=1.0;
-
-    /* The straightness test compares flatness criteria to running product of 
the tangent vector of
-     * the frenet frame projected onto each other tangent in the frame set.
-     */
-    for(int i=0; i<8; i++) {
-       for( int j=i+1; j<9; j++) {
-           if ((Xdot = Xdot * frames[0].xaxis * frames[1].xaxis) < 
BREP_SURFACE_FLATNESS) {
-                   return false;
-           }
-       }
-    }
-
-    return true;
+    return ON_Surface_IsStraight(frames, BREP_SURFACE_FLATNESS);
 }
 
 
 bool
 SurfaceTree::isFlatU(ON_Plane *frames)
 {
-    // check surface normals in U direction
-       double Ndot = 1.0;
-    if ((Ndot=frames[0].zaxis * frames[1].zaxis) < BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Ndot=Ndot * frames[2].zaxis * frames[3].zaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Ndot=Ndot * frames[5].zaxis * frames[7].zaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Ndot=Ndot * frames[6].zaxis * frames[8].zaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    }
-
-    // check for U twist within plane
-    double Xdot = 1.0;
-    if ((Xdot=frames[0].xaxis * frames[1].xaxis) < BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Xdot=Xdot * frames[2].xaxis * frames[3].xaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Xdot=Xdot * frames[5].xaxis * frames[7].xaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Xdot=Xdot * frames[6].xaxis * frames[8].xaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    }
-
-    return true;
+    ON_Surface_IsFlat_U(frames, BREP_SURFACE_FLATNESS);
 }
 
 
 bool
 SurfaceTree::isFlatV(ON_Plane *frames)
 {
-    // check surface normals in V direction
-       double Ndot = 1.0;
-    if ((Ndot=frames[0].zaxis * frames[3].zaxis) < BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Ndot=Ndot * frames[1].zaxis * frames[2].zaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Ndot=Ndot * frames[5].zaxis * frames[6].zaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Ndot=Ndot * frames[7].zaxis * frames[8].zaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    }
-
-    // check for V twist within plane
-    double Xdot = 1.0;
-    if ((Xdot=frames[0].xaxis * frames[3].xaxis) < BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Xdot=Xdot * frames[1].xaxis * frames[2].xaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Xdot=Xdot * frames[5].xaxis * frames[6].xaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    } else if ((Xdot=Xdot * frames[7].xaxis * frames[8].xaxis) < 
BREP_SURFACE_FLATNESS) {
-       return false;
-    }
-
-    return true;
+    ON_Surface_IsFlat_V(frames, BREP_SURFACE_FLATNESS);
 }
 
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to