Revision: 57223
          http://sourceforge.net/p/brlcad/code/57223
Author:   indianlarry
Date:     2013-08-28 14:24:01 +0000 (Wed, 28 Aug 2013)
Log Message:
-----------
Initial pullback using first order derivative (WIP currently tetsing resolving  
known trim points still have a handful of points that don't resolve generally 
due to singularities in the Jacobian plan to brute force those points through 
subdivsion for now )

Modified Paths:
--------------
    brlcad/branches/nurbs/src/librt/primitives/brep/brep.cpp

Modified: brlcad/branches/nurbs/src/librt/primitives/brep/brep.cpp
===================================================================
--- brlcad/branches/nurbs/src/librt/primitives/brep/brep.cpp    2013-08-28 
13:43:32 UTC (rev 57222)
+++ brlcad/branches/nurbs/src/librt/primitives/brep/brep.cpp    2013-08-28 
14:24:01 UTC (rev 57223)
@@ -2601,6 +2601,1006 @@
     }
 }
 
+
+bool surface_GetClosestPoint3dFirstOrder(
+       const ON_Surface *surf,
+        const ON_3dPoint& p,
+        ON_2dPoint& p2d,
+        ON_3dPoint& p3d,
+        double tol
+        )
+{
+    ON_3dPoint p0;
+    ON_2dPoint p2d0;
+    ON_3dVector ds,dt,dss,dst,dtt;
+    ON_3dVector T,K;
+    bool rc = false;
+    ON_Surface *mysurf = surf->Duplicate();
+
+
+    int prec = std::cerr.precision();
+    std::cerr.precision(15);
+
+    int u_spancnt = surf->SpanCount(0);
+    int v_spancnt = surf->SpanCount(1);
+    std::vector< std::vector<ON_BoundingBox> > bbox;
+    std::vector< std::vector<ON_3dVector> > normal;
+    std::vector< std::vector<ON_3dVector> > Ku;
+    std::vector< std::vector<ON_3dVector> > Kv;
+    std::vector< std::vector<ON_3dVector> > Tu;
+    std::vector< std::vector<ON_3dVector> > Tv;
+    std::vector< std::vector<ON_3dPoint> > P;
+    std::vector< std::vector<ON_3dVector> > Ds, Dt, Dss, Dst, Dtt;
+    std::vector< std::vector<double> > min_distance;
+    std::vector< std::vector<double> > max_distance;
+    std::vector< std::vector<bool> > skip;
+    double *uspan = new double[u_spancnt + 1];
+    double *vspan = new double[v_spancnt + 1];
+    double running_maxmin_distance = DBL_MAX;
+    ON_Interval u_dom = surf->Domain(0);
+    ON_Interval v_dom = surf->Domain(1);
+
+    // Set up sizes. (HEIGHT x WIDTH)
+    bbox.resize(u_spancnt + 1);
+    normal.resize(u_spancnt + 1);
+    Ku.resize(u_spancnt + 1);
+    Kv.resize(u_spancnt + 1);
+    Tu.resize(u_spancnt + 1);
+    Tv.resize(u_spancnt + 1);
+    P.resize(u_spancnt + 1);
+    Ds.resize(u_spancnt + 1);
+    Dt.resize(u_spancnt + 1);
+    Dss.resize(u_spancnt + 1);
+    Dst.resize(u_spancnt + 1);
+    Dtt.resize(u_spancnt + 1);
+    min_distance.resize(u_spancnt + 1);
+    max_distance.resize(u_spancnt + 1);
+    skip.resize(u_spancnt + 1);
+    for (int i = 0; i < u_spancnt+1; ++i) {
+       bbox[i].resize(v_spancnt + 1);
+       normal[i].resize(v_spancnt + 1);
+       Ku[i].resize(v_spancnt + 1);
+       Kv[i].resize(v_spancnt + 1);
+       Tu[i].resize(v_spancnt + 1);
+       Tv[i].resize(v_spancnt + 1);
+       P[i].resize(v_spancnt + 1);
+       Ds[i].resize(v_spancnt + 1);
+       Dt[i].resize(v_spancnt + 1);
+       Dss[i].resize(v_spancnt + 1);
+       Dst[i].resize(v_spancnt + 1);
+       Dtt[i].resize(v_spancnt + 1);
+       min_distance[i].resize(v_spancnt + 1);
+       max_distance[i].resize(v_spancnt + 1);
+       skip[i].resize(v_spancnt + 1);
+    }
+    for ( int u_span_index = 0; u_span_index < u_spancnt+1; u_span_index++ )
+    {
+       for ( int v_span_index = 0; v_span_index < v_spancnt+1; v_span_index++ )
+       {
+           skip[u_span_index][v_span_index] = true;
+       }
+    }
+    if ( mysurf->GetSpanVector(0,uspan) && mysurf->GetSpanVector(1,vspan)) {
+       ON_Interval u_interval;
+       ON_Interval v_interval;
+       for ( int u_span_index = 1; u_span_index < u_spancnt+1; u_span_index++ )
+       {
+           u_interval.Set(uspan[u_span_index-1],uspan[u_span_index]);
+           for ( int v_span_index = 1; v_span_index < v_spancnt+1; 
v_span_index++ )
+           {
+               v_interval.Set(vspan[v_span_index-1],vspan[v_span_index]);
+               mysurf = surf->Duplicate();
+               mysurf->Trim(0,u_interval);
+               mysurf->Trim(1,v_interval);
+               if 
(mysurf->GetBoundingBox(bbox[u_span_index][v_span_index],false)) {
+                   min_distance[u_span_index][v_span_index] = 
bbox[u_span_index][v_span_index].MinimumDistanceTo(p);
+                   if ( min_distance[u_span_index][v_span_index] <= 
running_maxmin_distance) {
+                       max_distance[u_span_index][v_span_index] = 
bbox[u_span_index][v_span_index].MaximumDistanceTo(p);
+                       ON_BoundingBox face_bbox;
+                       double max;
+                       face_bbox = bbox[u_span_index][v_span_index];
+                       // try closest maximum distance to each BB face
+                       // X
+                       face_bbox.m_min.x = face_bbox.m_max.x = 
bbox[u_span_index][v_span_index].m_min.x;
+                       max = face_bbox.MaximumDistanceTo(p);
+                       if (max < max_distance[u_span_index][v_span_index]) {
+                           max_distance[u_span_index][v_span_index] = max;
+                       }
+                       face_bbox.m_min.x = face_bbox.m_max.x = 
bbox[u_span_index][v_span_index].m_max.x;
+                       max = face_bbox.MaximumDistanceTo(p);
+                       if (max < max_distance[u_span_index][v_span_index]) {
+                           max_distance[u_span_index][v_span_index] = max;
+                       }
+                       face_bbox.m_min.x = 
bbox[u_span_index][v_span_index].m_min.x;
+                       // Y
+                       face_bbox.m_min.y = face_bbox.m_max.y = 
bbox[u_span_index][v_span_index].m_min.y;
+                       max = face_bbox.MaximumDistanceTo(p);
+                       if (max < max_distance[u_span_index][v_span_index]) {
+                           max_distance[u_span_index][v_span_index] = max;
+                       }
+                       face_bbox.m_min.y = face_bbox.m_max.y = 
bbox[u_span_index][v_span_index].m_max.y;
+                       max = face_bbox.MaximumDistanceTo(p);
+                       if (max < max_distance[u_span_index][v_span_index]) {
+                           max_distance[u_span_index][v_span_index] = max;
+                       }
+                       face_bbox.m_min.y = 
bbox[u_span_index][v_span_index].m_min.y;
+                       // Z
+                       face_bbox.m_min.z = face_bbox.m_max.z = 
bbox[u_span_index][v_span_index].m_min.z;
+                       max = face_bbox.MaximumDistanceTo(p);
+                       if (max < max_distance[u_span_index][v_span_index]) {
+                           max_distance[u_span_index][v_span_index] = max;
+                       }
+                       face_bbox.m_min.z = face_bbox.m_max.z = 
bbox[u_span_index][v_span_index].m_max.z;
+                       max = face_bbox.MaximumDistanceTo(p);
+                       if (max < max_distance[u_span_index][v_span_index]) {
+                           max_distance[u_span_index][v_span_index] = max;
+                       }
+
+                       if (max_distance[u_span_index][v_span_index] < 
running_maxmin_distance) {
+                           running_maxmin_distance = 
max_distance[u_span_index][v_span_index];
+                       }
+                       skip[u_span_index][v_span_index] = false;
+                   }
+               }
+           }
+       }
+       for ( int u_span_index = 1; u_span_index < u_spancnt+1; u_span_index++ )
+       {
+           for ( int v_span_index = 1; v_span_index < v_spancnt+1; 
v_span_index++ )
+           {
+               if ( min_distance[u_span_index][v_span_index] > 
running_maxmin_distance) {
+                   skip[u_span_index][v_span_index] = true;
+               }
+           }
+       }
+    }
+
+    for ( int u_span_index = 0; u_span_index < u_spancnt+1; u_span_index++ )
+    {
+       for ( int v_span_index = 0; v_span_index < v_spancnt+1; v_span_index++ )
+       {
+           if (surf->Ev2Der( uspan[u_span_index], vspan[v_span_index], 
P[u_span_index][v_span_index], Ds[u_span_index][v_span_index], 
Dt[u_span_index][v_span_index], Dss[u_span_index][v_span_index], 
Dst[u_span_index][v_span_index], Dtt[u_span_index][v_span_index])) {
+               ON_EvCurvature( Ds[u_span_index][v_span_index], 
Dss[u_span_index][v_span_index], Tu[u_span_index][v_span_index], 
Ku[u_span_index][v_span_index] );
+               ON_EvCurvature( Dt[u_span_index][v_span_index], 
Dtt[u_span_index][v_span_index], Tv[u_span_index][v_span_index], 
Kv[u_span_index][v_span_index] );
+               normal[u_span_index][v_span_index] = 
ON_CrossProduct(Ds[u_span_index][v_span_index],Dt[u_span_index][v_span_index]);
+               normal[u_span_index][v_span_index].Unitize();
+               if ((u_span_index > 0) && (v_span_index > 0)) {
+                   double udot_1 = 
normal[u_span_index-1][v_span_index-1]*normal[u_span_index][v_span_index-1];
+                   double udot_2 = 
normal[u_span_index-1][v_span_index]*normal[u_span_index][v_span_index];
+                   double vdot_1 = 
normal[u_span_index-1][v_span_index-1]*normal[u_span_index-1][v_span_index];
+                   double vdot_2 = 
normal[u_span_index][v_span_index-1]*normal[u_span_index][v_span_index];
+                   if ((udot_1 < 0.0) || (udot_2 < 0.0) || (vdot_1 < 0.0) || 
(vdot_2 < 0.0)) {
+                       double u[2][2];
+                       double v[2][2];
+                       u[0][0] = Ku[u_span_index-1][v_span_index-1].Length();
+                       u[0][1] = Ku[u_span_index-1][v_span_index].Length();
+                       u[1][0] = Ku[u_span_index][v_span_index-1].Length();
+                       u[1][1] = Ku[u_span_index][v_span_index].Length();
+                       v[0][0] = Kv[u_span_index-1][v_span_index-1].Length();
+                       v[0][1] = Kv[u_span_index-1][v_span_index].Length();
+                       v[1][0] = Kv[u_span_index][v_span_index-1].Length();
+                       v[1][1] = Kv[u_span_index][v_span_index].Length();
+
+                       double new_u1, new_u2;
+                       ON_3dPoint Pu[4];
+                       ON_3dVector Nu[4];
+                       if ((udot_1 < 0.0) || (udot_2 < 0.0)) {
+                           if (u[0][0] > u[0][1]) {
+                               new_u1 = uspan[u_span_index-1] + 1/u[0][0];
+                           } else {
+                               new_u1 = uspan[u_span_index] - 1/u[0][1];
+                           }
+                           if (u[1][0] > u[1][1]) {
+                               new_u2 = uspan[u_span_index-1] + 1/u[1][0];
+                           } else {
+                               new_u2 = uspan[u_span_index] - 1/u[1][1];
+                           }
+                           if (surf->Ev2Der( new_u1, vspan[v_span_index-1], 
Pu[0], ds, dt, dss, dst, dtt)) {
+                               Nu[0] = ON_CrossProduct(ds,dt);
+                               Nu[0].Unitize();
+                           }
+                           if (surf->Ev2Der( new_u2, vspan[v_span_index], 
Pu[1], ds, dt, dss, dst, dtt)) {
+                               Nu[1] = ON_CrossProduct(ds,dt);
+                               Nu[1].Unitize();
+                           }
+                       }
+                       double new_v1, new_v2;
+                       if ((vdot_1 < 0.0) || (vdot_2 < 0.0)) {
+                           if (v[0][0] > v[0][1]) {
+                               ON_2dVector  pullback;
+                               ON_3dPoint  newpoint;
+                               if 
(ON_Pullback3dVector(Kv[u_span_index-1][v_span_index-1],0.0,Ds[u_span_index-1][v_span_index-1],Dt[u_span_index-1][v_span_index-1],Dss[u_span_index-1][v_span_index-1],Dst[u_span_index-1][v_span_index-1],Dtt[u_span_index-1][v_span_index-1],pullback))
 {
+                                   if (((uspan[u_span_index-1] - pullback.x) > 
uspan[u_span_index-1]) &&
+                                           ((uspan[u_span_index-1] - 
pullback.x) < uspan[u_span_index]))
+                                       new_u1 = uspan[u_span_index-1] - 
pullback.x;
+                                   if (((vspan[v_span_index-1] - pullback.y) > 
vspan[v_span_index-1]) &&
+                                           ((vspan[v_span_index-1] - 
pullback.y) < vspan[v_span_index]))
+                                       new_v1 = vspan[v_span_index-1] - 
pullback.y;
+                                   newpoint = surf->PointAt(new_u1,new_v1);
+                               }
+
+                               new_v1 = vspan[v_span_index-1] + 1/v[0][0];
+                           } else {
+                               new_v1 = vspan[v_span_index] - 1/v[0][1];
+                           }
+                           if (v[1][0] > v[1][1]) {
+                               new_v2 = vspan[v_span_index-1] + 1/v[1][0];
+                           } else {
+                               new_v2 = vspan[v_span_index] - 1/v[1][1];
+                           }
+                           if (surf->Ev2Der( uspan[u_span_index-1], new_v1, 
Pu[2], ds, dt, dss, dst, dtt)) {
+                               Nu[2] = ON_CrossProduct(ds,dt);
+                               Nu[2].Unitize();
+                           }
+                           if (surf->Ev2Der( uspan[u_span_index], new_v2, 
Pu[3], ds, dt, dss, dst, dtt)) {
+                               Nu[3] = ON_CrossProduct(ds,dt);
+                               Nu[3].Unitize();
+                           }
+                       }
+                       continue;
+                   }
+               }
+           }
+       }
+    }
+
+    double current_distance = DBL_MAX;
+    for ( int u_span_index = 1; u_span_index < u_spancnt+1; u_span_index++ )
+    {
+       for ( int v_span_index = 1; v_span_index < v_spancnt+1; v_span_index++ )
+       {
+           if (skip[u_span_index][v_span_index] || (current_distance < tol) || 
(min_distance[u_span_index][v_span_index] > current_distance))
+               continue;
+           ON_Interval u_interval(uspan[u_span_index-1],uspan[u_span_index]);
+           ON_Interval v_interval(vspan[v_span_index-1],vspan[v_span_index]);
+
+
+           double udot_1 = 
normal[u_span_index-1][v_span_index-1]*normal[u_span_index][v_span_index-1];
+           double udot_2 = 
normal[u_span_index-1][v_span_index]*normal[u_span_index][v_span_index];
+           double vdot_1 = 
normal[u_span_index-1][v_span_index-1]*normal[u_span_index-1][v_span_index];
+           double vdot_2 = 
normal[u_span_index][v_span_index-1]*normal[u_span_index][v_span_index];
+
+
+           if ((udot_1 < 0.0) || (udot_2 < 0.0) || (vdot_1 < 0.0) || (vdot_2 < 
0.0)) {
+               bool notdone = true;
+               p2d0.x = (uspan[u_span_index - 1] + uspan[u_span_index])
+                       / 2.0;
+               p2d0.y = (vspan[v_span_index - 1] + vspan[v_span_index])
+                       / 2.0;
+               double previous_distance = DBL_MAX;
+               double distance;
+               ON_3dPoint working_p3d;
+               ON_3dPoint working_p2d;
+               int errcnt=0;
+/* need to subdivide while normals flip
+               double u0,u1,v0,v1;
+               u0 = uspan[u_span_index - 1]
+               while (notdone) {
+                   ON_3dVector subnormal;
+                   double stepu = (uspan[u_span_index] - uspan[u_span_index - 
1]) / (surf->Degree(0)+1);
+                   double stepv = (vspan[v_span_index] - vspan[v_span_index - 
1]) / (surf->Degree(1)+1);
+                   for(int iu = 0; iu <  surf->Degree(0)+1; iu++) {
+                       double u = uspan[u_span_index - 1] + iu * stepu;
+                       for(int iv=0; iv < surf->Degree(1)+1; iv++) {
+                           double v = vspan[v_span_index - 1] + iv * stepv;
+                           if (surf->Ev2Der(u, v, p0, ds,
+                                                       dt, dss, dst, dtt)) {
+                               subnormal = ON_CrossProduct(ds,dt);
+                               subnormal.Unitize();
+                           }
+                       }
+                   }
+               }
+               */
+               while (notdone
+                       && (surf->Ev2Der(p2d0.x, p2d0.y, p0, ds,
+                               dt, dss, dst, dtt))
+                       ) {
+                   if ((distance = p0.DistanceTo(p)) >= previous_distance) {
+                       if (++errcnt <= 10) {
+                           p2d0 = (p2d0 + working_p2d)/2.0;
+                           continue;
+                       } else {
+                           break;
+                       }
+                       /* if (++errcnt > 10) break; */
+                   } else {
+                       previous_distance = distance;
+                       working_p3d = p0;
+                       working_p2d = p2d0;
+                       errcnt=0;
+                   }
+                   ON_EvCurvature(ds, dt, T, K);
+                   ON_3dVector N = ON_CrossProduct(ds, dt);
+                   N.Unitize();
+                   ON_Plane plane(p0, N);
+                   ON_3dPoint q = plane.ClosestPointTo(p);
+                   ON_2dVector pullback;
+                   ON_3dVector vector = q - p0;
+                   double vlength = vector.Length();
+
+                   if (vlength > 0.0) {
+                       rc = true;
+
+                       if (ON_Pullback3dVector(vector, 0.0, ds, dt, dss, dst,
+                               dtt, pullback)) {
+                           p2d0 = p2d0 + pullback;
+                           if (!u_interval.Includes(p2d0.x, false)) {
+                               int i =
+                                       (u_interval.m_t[0] <= 
u_interval.m_t[1]) ?
+                                               0 : 1;
+                               p2d0.x =
+                                       (p2d0.x < u_interval.m_t[i]) ?
+                                               u_interval.m_t[i] :
+                                               u_interval.m_t[1 - i];
+                           }
+                           if (!v_interval.Includes(p2d0.y, false)) {
+                               int i =
+                                       (v_interval.m_t[0] <= 
v_interval.m_t[1]) ?
+                                               0 : 1;
+                               p2d0.y =
+                                       (p2d0.y < v_interval.m_t[i]) ?
+                                               v_interval.m_t[i] :
+                                               v_interval.m_t[1 - i];
+                           }
+                           /*
+                            if (distance < tol) {
+                            notdone = false;
+                            break;
+                            }
+                            */
+                       } else {
+                           notdone = false;
+                           rc = false;
+                           break;
+                       }
+                   } else {
+                       // can't get any closer
+                       rc = true;
+                       notdone = false;
+                       break;
+                   }
+               }
+               if (previous_distance < current_distance) {
+                   current_distance = previous_distance;
+                   p3d = working_p3d;
+                   p2d = working_p2d;
+               }
+               tol = 1.e-12;
+               if (current_distance > tol) {
+                   ON_2dPoint p2d_pass1 = p2d;
+                   double step = sqrt(current_distance/sqrt(2.0));
+                   //for now do slow four corner
+                   for(int ui = 0; ui < 2 && current_distance > tol; ui++) {
+                       /*
+                       p2d0.x = (p2d_pass1.x + uspan[u_span_index - 1 + 
ui])/2.0;
+                       if (ui == 0) {
+                           p2d0.x = p2d_pass1.x - (uspan[u_span_index] - 
uspan[u_span_index - 1])*0.01;
+                       } else {
+                           p2d0.x = p2d_pass1.x + (uspan[u_span_index] - 
uspan[u_span_index - 1])*0.01;
+                       }
+                       p2d0.x = (p2d_pass1.x + uspan[u_span_index - 1 + 
ui])/2.0;
+                       */
+                       for(int vi = 0; vi < 2 && current_distance > tol; vi++) 
{
+                           bool notdone = true;
+                           /*
+                           if (vi == 0) {
+                               p2d0.y = p2d_pass1.y - (vspan[v_span_index] - 
vspan[v_span_index - 1])*0.01;
+                           } else {
+                               p2d0.y = p2d_pass1.y + (vspan[v_span_index] - 
vspan[v_span_index - 1])*0.01;
+                           }
+                           p2d0.x = (p2d_pass1.x + uspan[u_span_index - 1 + 
ui])/2.0;
+                           p2d0.y = (p2d_pass1.y + vspan[v_span_index - 1 + 
vi])/2.0;
+                           if (ui == 0) {
+                               p2d0.x = p2d_pass1.x - (uspan[u_span_index] - 
uspan[u_span_index - 1])*0.01;
+                           } else {
+                               p2d0.x = p2d_pass1.x + (uspan[u_span_index] - 
uspan[u_span_index - 1])*0.01;
+                           }
+                           if (vi == 0) {
+                               p2d0.y = p2d_pass1.y - (vspan[v_span_index] - 
vspan[v_span_index - 1])*0.01;
+                           } else {
+                               p2d0.y = p2d_pass1.y + (vspan[v_span_index] - 
vspan[v_span_index - 1])*0.01;
+                           }
+                           p2d0.x = uspan[u_span_index - 1 + ui];
+                           p2d0.y = vspan[v_span_index - 1 + vi];
+                           */
+                           if (ui == 0) {
+                               p2d0.x = p2d_pass1.x - step;
+                           } else {
+                               p2d0.x = p2d_pass1.x + step;
+                           }
+                           if (vi == 0) {
+                               p2d0.y = p2d_pass1.y - step;
+                           } else {
+                               p2d0.y = p2d_pass1.y + step;
+                           }
+                           p2d0.x = (p2d_pass1.x + uspan[u_span_index - 1 + 
ui])/2.0;
+                           p2d0.y = (p2d_pass1.y + vspan[v_span_index - 1 + 
vi])/2.0;
+                           if (!u_interval.Includes(p2d0.x, false)) {
+                               int i =
+                                       (u_interval.m_t[0] <= 
u_interval.m_t[1]) ?
+                                               0 : 1;
+                               p2d0.x =
+                                       (p2d0.x < u_interval.m_t[i]) ?
+                                               u_interval.m_t[i] :
+                                               u_interval.m_t[1 - i];
+                           }
+                           if (!v_interval.Includes(p2d0.y, false)) {
+                               int i =
+                                       (v_interval.m_t[0] <= 
v_interval.m_t[1]) ?
+                                               0 : 1;
+                               p2d0.y =
+                                       (p2d0.y < v_interval.m_t[i]) ?
+                                               v_interval.m_t[i] :
+                                               v_interval.m_t[1 - i];
+                           }
+                           ON_3dPoint working_p3d;
+                           ON_2dPoint working_p2d;
+                           int errcnt=0;
+                           double previous_distance = DBL_MAX;
+                           double distance;
+                           ON_2dVector pullback;
+
+                           while (notdone
+                                   && (surf->Ev2Der(p2d0.x, p2d0.y, p0, ds,
+                                           dt, dss, dst, dtt))) {
+                               if ((distance = p0.DistanceTo(p)) >= 
previous_distance) {
+                                   if (++errcnt <= 10) {
+                                       p2d0 = (p2d0 + working_p2d)/2.0;
+                                       continue;
+                                   } else {
+                                       break;
+                                   }
+                                   //if (++errcnt > 10) break;
+                               } else {
+                                   previous_distance = distance;
+                                   working_p3d = p0;
+                                   working_p2d = p2d0;
+                                   errcnt=0;
+                               }
+                               ON_EvCurvature(ds, dt, T, K);
+                               ON_3dVector N = ON_CrossProduct(ds, dt);
+                               N.Unitize();
+                               ON_Plane plane(p0, N);
+                               ON_3dPoint q = plane.ClosestPointTo(p);
+                               //ON_2dVector pullback;
+                               ON_3dVector vector = q - p0;
+                               double vlength = vector.Length();
+
+                               if (vlength > 0.0) {
+                                   rc = true;
+
+                                   if (ON_Pullback3dVector(vector, vlength, 
ds, dt, dss, dst,
+                                           dtt, pullback)) {
+                                       p2d0 = p2d0 + pullback;
+                                       if (!u_interval.Includes(p2d0.x, 
false)) {
+                                           int i =
+                                                   (u_interval.m_t[0] <= 
u_interval.m_t[1]) ?
+                                                           0 : 1;
+                                           p2d0.x =
+                                                   (p2d0.x < 
u_interval.m_t[i]) ?
+                                                           u_interval.m_t[i] :
+                                                           u_interval.m_t[1 - 
i];
+                                       }
+                                       if (!v_interval.Includes(p2d0.y, 
false)) {
+                                           int i =
+                                                   (v_interval.m_t[0] <= 
v_interval.m_t[1]) ?
+                                                           0 : 1;
+                                           p2d0.y =
+                                                   (p2d0.y < 
v_interval.m_t[i]) ?
+                                                           v_interval.m_t[i] :
+                                                           v_interval.m_t[1 - 
i];
+                                       }
+                                   } else {
+                                       const double ds_o_V = ds*vector;
+                                       const double dt_o_V = dt*vector;
+                                       const double ds_o_ds = ds*ds;
+                                       const double ds_o_dt = ds*dt;
+                                       const double dt_o_ds = dt*ds;
+                                       const double dt_o_dt = dt*dt;
+
+                                       int s_sign = sign(ds_o_V);
+                                       int t_sign = sign(dt_o_V);
+                                       double s_delta = 0.0;
+                                       if (fabs(ds_o_V) > 0.0) {
+                                           s_delta = vlength / ds_o_V / 
ds_o_ds;
+                                       } else {
+                                           s_delta = 0.0;
+                                       }
+                                       double t_delta = 0.0;
+                                       if (fabs(dt_o_V) > 0.0) {
+                                           t_delta = vlength / dt_o_V / 
dt_o_dt;
+                                       } else {
+                                           t_delta = 0.0;
+                                       }
+                                       p2d0.x = p2d0.x + s_delta;
+                                       p2d0.y = p2d0.y + t_delta;
+                                       // perform jittered perturbation in 
parametric domain....
+                                       //p2d0.x = p2d0.x + .1 * 
(drand48()-0.5) * (uspan[u_span_index] - uspan[u_span_index - 1]);
+                                       //p2d0.y = p2d0.y + .1 * 
(drand48()-0.5) * (vspan[v_span_index] - vspan[v_span_index - 1]);
+                                       if (!u_interval.Includes(p2d0.x, 
false)) {
+                                           int i =
+                                                   (u_interval.m_t[0] <= 
u_interval.m_t[1]) ?
+                                                           0 : 1;
+                                           p2d0.x =
+                                                   (p2d0.x < 
u_interval.m_t[i]) ?
+                                                           u_interval.m_t[i] :
+                                                           u_interval.m_t[1 - 
i];
+                                       }
+                                       if (!v_interval.Includes(p2d0.y, 
false)) {
+                                           int i =
+                                                   (v_interval.m_t[0] <= 
v_interval.m_t[1]) ?
+                                                           0 : 1;
+                                           p2d0.y =
+                                                   (p2d0.y < 
v_interval.m_t[i]) ?
+                                                           v_interval.m_t[i] :
+                                                           v_interval.m_t[1 - 
i];
+                                       }
+
+                                   }
+                               } else {
+                                   // can't get any closer
+                                   rc = true;
+                                   notdone = false;
+                                   break;
+                               }
+                           }
+                           if (previous_distance < current_distance) {
+                               current_distance = previous_distance;
+                               p3d = working_p3d;
+                               p2d = working_p2d;
+                           }
+                       }
+                   }
+                   for(int ui = 0; ui < 2 && current_distance > tol; ui++) {
+                       p2d0.x = (p2d_pass1.x + uspan[u_span_index - 1 + 
ui])/2.0;
+                       if (ui == 0) {
+                           p2d0.x = p2d_pass1.x - (uspan[u_span_index] - 
uspan[u_span_index - 1])*0.01;
+                       } else {
+                           p2d0.x = p2d_pass1.x + (uspan[u_span_index] - 
uspan[u_span_index - 1])*0.01;
+                       }
+                       p2d0.y = p2d_pass1.y;
+                       bool notdone = true;
+                       ON_3dPoint working_p3d;
+                       ON_2dPoint working_p2d;
+                       int errcnt=0;
+                       double previous_distance = DBL_MAX;
+                       double distance;
+                       ON_2dVector pullback;
+
+                       while (notdone
+                               && (surf->Ev2Der(p2d0.x, p2d0.y, p0, ds,
+                                       dt, dss, dst, dtt))) {
+                           if ((distance = p0.DistanceTo(p)) >= 
previous_distance) {
+                               if (++errcnt <= 10) {
+                                   p2d0 = (p2d0 + working_p2d)/2.0;
+                                   continue;
+                               } else {
+                                   break;
+                               }
+                               //if (++errcnt > 10) break;
+                           } else {
+                               previous_distance = distance;
+                               working_p3d = p0;
+                               working_p2d = p2d0;
+                               errcnt=0;
+                           }
+                           ON_EvCurvature(ds, dt, T, K);
+                           ON_3dVector N = ON_CrossProduct(ds, dt);
+                           N.Unitize();
+                           ON_Plane plane(p0, N);
+                           ON_3dPoint q = plane.ClosestPointTo(p);
+                           //ON_2dVector pullback;
+                           ON_3dVector vector = q - p0;
+                           double vlength = vector.Length();
+
+                           if (vlength > 0.0) {
+                               rc = true;
+
+                               if (ON_Pullback3dVector(vector, 0.0, ds, dt, 
dss, dst,
+                                       dtt, pullback)) {
+                                   p2d0 = p2d0 + pullback;
+                                   if (!u_interval.Includes(p2d0.x, false)) {
+                                       int i =
+                                               (u_interval.m_t[0] <= 
u_interval.m_t[1]) ?
+                                                       0 : 1;
+                                       p2d0.x =
+                                               (p2d0.x < u_interval.m_t[i]) ?
+                                                       u_interval.m_t[i] :
+                                                       u_interval.m_t[1 - i];
+                                   }
+                                   if (!v_interval.Includes(p2d0.y, false)) {
+                                       int i =
+                                               (v_interval.m_t[0] <= 
v_interval.m_t[1]) ?
+                                                       0 : 1;
+                                       p2d0.y =
+                                               (p2d0.y < v_interval.m_t[i]) ?
+                                                       v_interval.m_t[i] :
+                                                       v_interval.m_t[1 - i];
+                                   }
+                               } else {
+                                   notdone = false;
+                                   rc = false;
+                                   break;
+                               }
+                           } else {
+                               // can't get any closer
+                               rc = true;
+                               notdone = false;
+                               break;
+                           }
+                       }
+                       if (previous_distance < current_distance) {
+                           current_distance = previous_distance;
+                           p3d = working_p3d;
+                           p2d = working_p2d;
+                       }
+                   }
+                   for(int vi = 0; vi < 2 && current_distance > tol; vi++) {
+                       bool notdone = true;
+                       p2d0.x = p2d_pass1.x;
+                       if (vi == 0) {
+                           p2d0.y = p2d_pass1.y - (vspan[v_span_index] - 
vspan[v_span_index - 1])*0.01;
+                       } else {
+                           p2d0.y = p2d_pass1.y + (vspan[v_span_index] - 
vspan[v_span_index - 1])*0.01;
+                       }
+                       ON_3dPoint working_p3d;
+                       ON_2dPoint working_p2d;
+                       int errcnt=0;
+                       double previous_distance = DBL_MAX;
+                       double distance;
+                       ON_2dVector pullback;
+
+                       while (notdone
+                               && (surf->Ev2Der(p2d0.x, p2d0.y, p0, ds,
+                                       dt, dss, dst, dtt))) {
+                           if ((distance = p0.DistanceTo(p)) >= 
previous_distance) {
+                               if (++errcnt <= 10) {
+                                   p2d0 = (p2d0 + working_p2d)/2.0;
+                                   continue;
+                               } else {
+                                   break;
+                               }
+                               //if (++errcnt > 10) break;
+                           } else {
+                               previous_distance = distance;
+                               working_p3d = p0;
+                               working_p2d = p2d0;
+                               errcnt=0;
+                           }
+                           ON_EvCurvature(ds, dt, T, K);
+                           ON_3dVector N = ON_CrossProduct(ds, dt);
+                           N.Unitize();
+                           ON_Plane plane(p0, N);
+                           ON_3dPoint q = plane.ClosestPointTo(p);
+                           //ON_2dVector pullback;
+                           ON_3dVector vector = q - p0;
+                           double vlength = vector.Length();
+
+                           if (vlength > 0.0) {
+                               rc = true;
+
+                               if (ON_Pullback3dVector(vector, 0.0, ds, dt, 
dss, dst,
+                                       dtt, pullback)) {
+                                   p2d0 = p2d0 + pullback;
+                                   if (!u_interval.Includes(p2d0.x, false)) {
+                                       int i =
+                                               (u_interval.m_t[0] <= 
u_interval.m_t[1]) ?
+                                                       0 : 1;
+                                       p2d0.x =
+                                               (p2d0.x < u_interval.m_t[i]) ?
+                                                       u_interval.m_t[i] :
+                                                       u_interval.m_t[1 - i];
+                                   }
+                                   if (!v_interval.Includes(p2d0.y, false)) {
+                                       int i =
+                                               (v_interval.m_t[0] <= 
v_interval.m_t[1]) ?
+                                                       0 : 1;
+                                       p2d0.y =
+                                               (p2d0.y < v_interval.m_t[i]) ?
+                                                       v_interval.m_t[i] :
+                                                       v_interval.m_t[1 - i];
+                                   }
+                               } else {
+                                   notdone = false;
+                                   rc = false;
+                                   break;
+                               }
+                           } else {
+                               // can't get any closer
+                               rc = true;
+                               notdone = false;
+                               break;
+                           }
+                       }
+                       if (previous_distance < current_distance) {
+                           current_distance = previous_distance;
+                           p3d = working_p3d;
+                           p2d = working_p2d;
+                       }
+                   }
+               }
+           } else {
+               bool notdone = true;
+               p2d0.x = (uspan[u_span_index - 1] + uspan[u_span_index])
+                       / 2.0;
+               p2d0.y = (vspan[v_span_index - 1] + vspan[v_span_index])
+                       / 2.0;
+               double previous_distance = DBL_MAX;
+               double distance;
+               ON_3dPoint working_p3d;
+               ON_3dPoint working_p2d;
+               int errcnt=0;
+
+               while (notdone
+                       && (surf->Ev2Der(p2d0.x, p2d0.y, p0, ds,
+                               dt, dss, dst, dtt))
+                       ) {
+                   if ((distance = p0.DistanceTo(p)) >= previous_distance) {
+                       if (++errcnt <= 10) {
+                           p2d0 = (p2d0 + working_p2d)/2.0;
+                           continue;
+                       } else {
+                           break;
+                       }
+                       //if (++errcnt > 10) break;
+                   } else {
+                       previous_distance = distance;
+                       working_p3d = p0;
+                       working_p2d = p2d0;
+                       errcnt=0;
+                   }
+                   ON_EvCurvature(ds, dt, T, K);
+                   ON_3dVector N = ON_CrossProduct(ds, dt);
+                   N.Unitize();
+                   ON_Plane plane(p0, N);
+                   ON_3dPoint q = plane.ClosestPointTo(p);
+                   ON_2dVector pullback;
+                   ON_3dVector vector = q - p0;
+                   double vlength = vector.Length();
+
+                   if (vlength > 0.0) {
+                       rc = true;
+
+                       if (ON_Pullback3dVector(vector, 0.0, ds, dt, dss, dst,
+                               dtt, pullback)) {
+                           p2d0 = p2d0 + pullback;
+                           if (!u_interval.Includes(p2d0.x, false)) {
+                               int i =
+                                       (u_interval.m_t[0] <= 
u_interval.m_t[1]) ?
+                                               0 : 1;
+                               p2d0.x =
+                                       (p2d0.x < u_interval.m_t[i]) ?
+                                               u_interval.m_t[i] :
+                                               u_interval.m_t[1 - i];
+                           }
+                           if (!v_interval.Includes(p2d0.y, false)) {
+                               int i =
+                                       (v_interval.m_t[0] <= 
v_interval.m_t[1]) ?
+                                               0 : 1;
+                               p2d0.y =
+                                       (p2d0.y < v_interval.m_t[i]) ?
+                                               v_interval.m_t[i] :
+                                               v_interval.m_t[1 - i];
+                           }
+                           /*
+                            if (distance < tol) {
+                            notdone = false;
+                            break;
+                            }
+                            */
+                       } else {
+                           notdone = false;
+                           rc = false;
+                           break;
+                       }
+                   } else {
+                       // can't get any closer
+                       rc = true;
+                       notdone = false;
+                       break;
+                   }
+               }
+               if (previous_distance < current_distance) {
+                   current_distance = previous_distance;
+                   p3d = working_p3d;
+                   p2d = working_p2d;
+               }
+           }
+       }
+    }
+
+    std::cerr.precision(prec);
+    return rc;
+}
+
+
+bool trim_GetClosestPoint3dFirstOrder(
+       const ON_BrepTrim& trim,
+        const ON_3dPoint& p,
+        ON_2dPoint& p2d,
+        double& t,
+        double tol,
+        const ON_Interval* interval,
+        bool print
+        )
+{
+    bool rc = false;
+    const ON_Surface *surf = trim.SurfaceOf();
+    double t0 = interval->Mid();
+    ON_3dPoint p3d;
+    ON_3dPoint p0;
+    ON_3dVector ds,dt,dss,dst,dtt;
+    ON_3dVector T,K;
+    int prec = std::cerr.precision();
+    ON_BoundingBox tight_bbox;
+    std::vector<ON_BoundingBox> bbox;
+
+    std::cerr.precision(15);
+
+    ON_Curve *c = trim.Brep()->m_C2[trim.m_c2i];
+    ON_Interval curve_interval = c->Domain();
+    ON_NurbsCurve N;
+    if ( 0 == c->GetNurbForm(N) )
+      return false;
+    if ( N.m_order < 2 || N.m_cv_count < N.m_order )
+      return false;
+
+    curve_interval = N.Domain();
+    ON_Curve *bc = c->Duplicate();
+    bc->Trim(*interval);
+    ON_BoundingBox bb = bc->BoundingBox();
+    p2d = trim.PointAt(t);
+    if (surface_GetClosestPoint3dFirstOrder(surf,p,p2d,p3d,tol)) {
+       ON_3dPoint test2dp = surf->PointAt(p2d.x,p2d.y);
+       ON_BezierCurve B;
+       bool bGrowBox = false;
+       ON_3dVector d1,d2;
+       double max_dist_to_closest_pt = DBL_MAX;
+       ON_Interval *span_interval = new ON_Interval[N.m_cv_count - N.m_order + 
1];
+       double *min_distance = new double[N.m_cv_count - N.m_order + 1];
+       double *max_distance = new double[N.m_cv_count - N.m_order + 1];
+       bool *skip = new bool[N.m_cv_count - N.m_order + 1];
+       bbox.resize(N.m_cv_count - N.m_order + 1);
+       for ( int span_index = 0; span_index <= N.m_cv_count - N.m_order; 
span_index++ )
+       {
+           skip[span_index] = true;
+         if ( !(N.m_knot[span_index + N.m_order-2] < N.m_knot[span_index + 
N.m_order-1]) )
+           continue;
+
+         // check for span out of interval
+         int i = (interval->m_t[0] <= interval->m_t[1]) ? 0 : 1;
+         if ( N.m_knot[span_index + N.m_order-2] > interval->m_t[1-i] )
+           continue;
+         if ( N.m_knot[span_index + N.m_order-1] < interval->m_t[i] )
+           continue;
+
+         if ( !N.ConvertSpanToBezier( span_index, B ) )
+           continue;
+         ON_Interval bi = B.Domain();
+         if ( !B.GetTightBoundingBox(tight_bbox,bGrowBox,NULL) )
+           continue;
+         bbox[span_index] = tight_bbox;
+         d1 = tight_bbox.m_min - p2d;
+         d2 = tight_bbox.m_max - p2d;
+         min_distance[span_index] = tight_bbox.MinimumDistanceTo(p2d);
+
+         if (print == true) {
+               std::cout << "in bbox_" << span_index << " rpp " << 
bbox[span_index].m_min.x << " " << bbox[span_index].m_max.x << " " << 
bbox[span_index].m_min.y << " " << bbox[span_index].m_max.y << " -0.001 0.001" 
<< std::endl;
+         }
+         if (min_distance[span_index] > max_dist_to_closest_pt) {
+             max_distance[span_index] = DBL_MAX;
+             continue;
+         }
+         skip[span_index] = false;
+         span_interval[span_index].m_t[0] = ((N.m_knot[span_index + 
N.m_order-2]) < interval->m_t[i]) ? interval->m_t[i] : N.m_knot[span_index + 
N.m_order-2];
+         span_interval[span_index].m_t[1] = ((N.m_knot[span_index + 
N.m_order-1]) > interval->m_t[1 -i]) ? interval->m_t[1 -i] : 
(N.m_knot[span_index + N.m_order-1]);
+         ON_3dPoint 
d1sq(d1.x*d1.x,d1.y*d1.y,0.0),d2sq(d2.x*d2.x,d2.y*d2.y,0.0);
+         double distancesq;
+         if(d1sq.x < d2sq.x) {
+           if (d1sq.y < d2sq.y) {
+               if ((d1sq.x + d2sq.y) < (d2sq.x + d1sq.y)) {
+                   distancesq = d1sq.x + d2sq.y;
+               } else {
+                   distancesq = d2sq.x + d1sq.y;
+               }
+           } else {
+               if ((d1sq.x + d1sq.y) < (d2sq.x + d2sq.y)) {
+                   distancesq = d1sq.x + d1sq.y;
+               } else {
+                   distancesq = d2sq.x + d2sq.y;
+               }
+           }
+         } else {
+           if (d1sq.y < d2sq.y) {
+               if ((d1sq.x + d1sq.y) < (d2sq.x + d2sq.y)) {
+                   distancesq = d1sq.x + d1sq.y;
+               } else {
+                   distancesq = d2sq.x + d2sq.y;
+               }
+           } else {
+               if ((d1sq.x + d2sq.y) < (d2sq.x + d1sq.y)) {
+                   distancesq = d1sq.x + d2sq.y;
+               } else {
+                   distancesq = d2sq.x + d1sq.y;
+               }
+           }
+         }
+         max_distance[span_index] = sqrt(distancesq);
+         if (max_distance[span_index] < max_dist_to_closest_pt) {
+             max_dist_to_closest_pt = max_distance[span_index];
+         }
+       }
+       for ( int span_index = 0; span_index <= N.m_cv_count - N.m_order; 
span_index++ )
+       {
+
+         if ( skip[span_index] )
+           continue;
+
+         if (min_distance[span_index] > max_dist_to_closest_pt) {
+             skip[span_index] = true;
+             continue;
+         }
+
+       }
+
+       ON_3dPoint q;
+       ON_3dPoint point;
+       double closest_distance = DBL_MAX;
+       double closestT = DBL_MAX;
+       for ( int span_index = 0; span_index <= N.m_cv_count - N.m_order; 
span_index++ )
+       {
+           if (skip[span_index]) {
+               continue;
+           }
+           t0 = span_interval[span_index].Mid();
+           bool closestfound = false;
+           bool notdone = true;
+           double distance, previous_distance = DBL_MAX;
+           ON_3dVector firstDervative, secondDervative;
+           while (notdone
+                   && trim.Ev2Der(t0, point, firstDervative, secondDervative)
+                   && ON_EvCurvature(firstDervative, secondDervative, T, K)) {
+               ON_Line line(point, point + 100.0 * T);
+               q = line.ClosestPointTo(p2d);
+               double delta_t = (firstDervative * (q - point))
+                       / (firstDervative * firstDervative);
+               double new_t0 = t0 + delta_t;
+               if (!span_interval[span_index].Includes(new_t0, false)) {
+                   // limit to interval
+                   int i = (span_interval[span_index].m_t[0] <= 
span_interval[span_index].m_t[1]) ? 0 : 1;
+                   new_t0 =
+                           (new_t0 < span_interval[span_index].m_t[i]) ?
+                                   span_interval[span_index].m_t[i] : 
span_interval[span_index].m_t[1 - i];
+               }
+               delta_t = new_t0 - t0;
+               t0 = new_t0;
+               point = trim.PointAt(t0);
+               distance = point.DistanceTo(p2d);
+               if (distance < previous_distance) {
+                   closestfound = true;
+                   closestT = t0;
+                   previous_distance = distance;
+                   if (fabs(delta_t) < tol) {
+                       notdone = false;
+                   }
+               } else {
+                   notdone = false;
+               }
+           }
+           if (closestfound && (distance < closest_distance)) {
+               closest_distance = distance;
+               rc = true;
+               t = closestT;
+           }
+       }
+    }
+    std::cerr.precision(prec);
+
+    return rc;
+}
+
+
 void poly2tri_CDT(struct bu_list *vhead, ON_BrepFace &face,
        const struct rt_tess_tol *ttol, const struct bn_tol *tol,
        const struct rt_view_info *info, bool watertight = false, int plottype =
@@ -2669,8 +3669,78 @@
                        ON_3dPoint *p3d = (*i).second;
                        if (++i == param_points3d->end())
                            continue;
-
+#define PULLBACK_TESTING
+#ifdef PULLBACK_TESTING
+                       int fi = face.m_face_index;
+                       double tpercent = t;
+                       ON_Interval interval = trim->Domain();
+                       if (trim->Edge()->IsClosed()) {
+                           if (NEAR_EQUAL(t, 0.0, tol->dist_sq)) {
+                               t = interval.m_t[0];
+                               //interval.m_t[1] = interval.Mid();
+                           } else if (NEAR_EQUAL(t, 1.0, tol->dist_sq)) {
+                               t = interval.m_t[1];
+                               //interval.m_t[0] = interval.Mid();
+                           } else {
+                               t = interval.Mid();
+                           }
+                       } else {
+                           t = interval.Mid();
+                       }
+                       bool print = false;
+                       ON_2dPoint new2d = p2d;
+                       if (trim_GetClosestPoint3dFirstOrder(*trim, *p3d, new2d,
+                               t, tol->dist, &interval, print)) {
+                           ON_2dPoint tp2d = trim->PointAt(t);
+                           ON_3dPoint tp3d = s->PointAt(tp2d.x, tp2d.y);
+                           ON_3dPoint tp3d2 = s->PointAt(p2d.x, p2d.y);
+                           ON_3dPoint tp3d3 = s->PointAt(new2d.x, new2d.y);
+                           /*
+                            if (!NEAR_EQUAL(t,(t0 + (t1 - t0) * 
tpercent),tol->dist_sq)) {
+                            std::cerr << "First Order failed for Face - " << 
fi << std::endl;
+                            std::cerr << "     tpercent: " << tpercent << " 
(li=" << li << ")" << " (lti=" << lti << ")"<< std::endl;
+                            std::cerr << "     found: " << t << " should be: " 
<< (t0 + (t1 - t0) * tpercent) << ")" << std::endl;
+                            std::cerr << "     p3d: < " << p3d->x << ", " << 
p3d->y << ", " << p3d->z << " >" << std::endl;
+                            std::cerr << "     tp3d: < " << tp3d.x << ", " << 
tp3d.y << ", " << tp3d.z << " >" << std::endl;
+                            std::cerr << "     p2d: < " << p2d.x << ", " << 
p2d.y << ", 0 >" << std::endl;
+                            std::cerr << "     tp2d: < " << tp2d.x << ", " << 
tp2d.y << ", 0 >" << std::endl;
+                            }
+                            */
+                           double test_dist = p3d->DistanceTo(tp3d);
+                           double test_dist2 = p3d->DistanceTo(tp3d2);
+                           double test_dist3 = p3d->DistanceTo(tp3d3);
+                           if (!NEAR_ZERO(test_dist,tol->dist_sq)) {
+                               ////////////////////
+                               int prec = std::cerr.precision();
+                               std::cerr.precision(15);
+                               ////////////////////
+                               std::cerr << "First Order failed for Face - "
+                                       << fi << std::endl;
+                               std::cerr << "     tpercent: " << tpercent
+                                       << " (li=" << li << ")" << " (lti="
+                                       << lti << ")" << std::endl;
+                               std::cerr << "     found: " << t
+                                       << " should be: "
+                                       << (t0 + (t1 - t0) * tpercent) << ")"
+                                       << std::endl;
+                               std::cerr << "     p3d: < " << p3d->x << ", "
+                                       << p3d->y << ", " << p3d->z << " >"
+                                       << std::endl;
+                               std::cerr << "     tp3d: < " << tp3d.x << ", "
+                                       << tp3d.y << ", " << tp3d.z << " >"
+                                       << std::endl;
+                               std::cerr << "     p2d: < " << p2d.x << ", "
+                                       << p2d.y << ", 0 >" << std::endl;
+                               std::cerr << "     tp2d: < " << tp2d.x << ", "
+                                       << tp2d.y << ", 0 >" << std::endl;
+                               std::cerr.precision(prec);
+                           }
+                       } else {
+                           p2d = trim->PointAt(t);
+                       }
+#else
                        p2d = trim->PointAt(t0 + (t1 - t0) * t);
+#endif
 
                        // map point to last entry to 3d point
                        p2t::Point *p = new p2t::Point(p2d.x, p2d.y);

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


------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to