Index: src/proc-db/CMakeLists.txt
===================================================================
--- src/proc-db/CMakeLists.txt	(revision 59234)
+++ src/proc-db/CMakeLists.txt	(working copy)
@@ -14,8 +14,8 @@
 # where they provide some conceivable value to an end user.
 BRLCAD_ADDEXEC(bottest bottest.c libwdb NO_INSTALL)
 BRLCAD_ADDEXEC(brep_cobb brep_cobb.cpp "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
-BRLCAD_ADDEXEC(brep_cube brep_cube.cpp "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
-BRLCAD_ADDEXEC(brep_simple brep_simple.cpp "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
+BRLCAD_ADDEXEC(brep_cube "brep_cube.cpp;twistedcube.cpp" "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
+BRLCAD_ADDEXEC(brep_simple "brep_simple.cpp;twistedcube.cpp" "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
 BRLCAD_ADDEXEC(brepintersect brepintersect.cpp "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
 BRLCAD_ADDEXEC(breplicator breplicator.cpp "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
 BRLCAD_ADDEXEC(contours contours.c libwdb NO_INSTALL)
@@ -23,7 +23,7 @@
 BRLCAD_ADDEXEC(nmgmodel nmgmodel.c libwdb NO_INSTALL)
 BRLCAD_ADDEXEC(pipetest pipetest.c libwdb NO_INSTALL)
 BRLCAD_ADDEXEC(spltest spltest.c libwdb NO_INSTALL)
-BRLCAD_ADDEXEC(surfaceintersect surfaceintersect.cpp "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
+BRLCAD_ADDEXEC(surfaceintersect "surfaceintersect.cpp;twistedcube.cpp" "libwdb;${OPENNURBS_LIBRARY}" NO_STRICT NO_INSTALL)
 BRLCAD_ADDEXEC(tea_nmg tea_nmg.c libwdb NO_INSTALL)
 BRLCAD_ADDEXEC(tube tube.c "libwdb;${M_LIBRARY}" NO_INSTALL)
 BRLCAD_ADDEXEC(wdb_example wdb_example.c libwdb NO_INSTALL)
@@ -62,6 +62,7 @@
 
 
 set(proc-db_ignore_files
+  twistedcube.hpp
   brepintersect.h
   metaballs.pl
   mkbuilding.h
Index: src/proc-db/brep_cube.cpp
===================================================================
--- src/proc-db/brep_cube.cpp	(revision 59234)
+++ src/proc-db/brep_cube.cpp	(working copy)
@@ -56,6 +56,8 @@
 /* without OBJ_BREP, this entire procedural example is disabled */
 #ifdef OBJ_BREP
 
+#include "twistedcube.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -67,9 +69,8 @@
 }
 #endif
 
-
 /* Prevent enum conflict with vmath.h */
-namespace {
+namespace  {
 
 enum {
     A, B, C, D, E, F, G, H
@@ -83,25 +84,7 @@
     ABCD, BFGC, FEHG, EADH, EFBA, DCGH
 };
 
-ON_Curve*
-TwistedCubeEdgeCurve(const ON_3dPoint& from, const ON_3dPoint& to)
-{
-    // creates a 3d line segment to be used as a 3d curve in an ON_Brep
-    ON_Curve* c3d = new ON_LineCurve(from, to);
-    c3d->SetDomain(0.0, 1.0); // XXX is this UV bounds?
-    return c3d;
-}
-
 void
-MakeTwistedCubeEdge(ON_Brep& brep, int from, int to, int curve)
-{
-    ON_BrepVertex& v0 = brep.m_V[from];
-    ON_BrepVertex& v1 = brep.m_V[to];
-    ON_BrepEdge& edge = brep.NewEdge(v0, v1, curve);
-    edge.m_tolerance = 0.0; // exact!
-}
-
-void
 MakeTwistedCubeEdges(ON_Brep& brep)
 {
     MakeTwistedCubeEdge(brep, A, B, AB);
@@ -118,165 +101,7 @@
     MakeTwistedCubeEdge(brep, D, H, DH);
 }
 
-ON_Surface*
-TwistedCubeSideSurface(const ON_3dPoint& SW, const ON_3dPoint& SE, const ON_3dPoint& NE, const ON_3dPoint& NW)
-{
-    ON_NurbsSurface* pNurbsSurface = new ON_NurbsSurface(3, // dimension
-							 0, // not rational
-							 2, // u order
-							 2, // v order,
-							 2, // number of control vertices in u
-							 2 // number of control verts in v
-	);
-    pNurbsSurface->SetCV(0, 0, SW);
-    pNurbsSurface->SetCV(1, 0, SE);
-    pNurbsSurface->SetCV(1, 1, NE);
-    pNurbsSurface->SetCV(0, 1, NW);
-    // u knots
-    pNurbsSurface->SetKnot(0, 0, 0.0);
-    pNurbsSurface->SetKnot(0, 1, 1.0);
-    // v knots
-    pNurbsSurface->SetKnot(1, 0, 0.0);
-    pNurbsSurface->SetKnot(1, 1, 1.0);
-
-    return pNurbsSurface;
-}
-
-ON_Curve*
-TwistedCubeTrimmingCurve(const ON_Surface& s,
-			 int side // 0 = SW to SE, 1 = SE to NE, 2 = NE to NW, 3 = NW, SW
-    )
-{
-    // a trimming curve is a 2d curve whose image lies in the surface's
-    // domain. The "active" portion of the surface is to the left of the
-    // trimming curve (looking down the orientation of the curve). An
-    // outer trimming loop consists of a simple closed curve running
-    // counter-clockwise around the region it trims
-
-    ON_2dPoint from, to;
-    double u0, u1, v0, v1;
-    s.GetDomain(0, &u0, &u1);
-    s.GetDomain(1, &v0, &v1);
-
-    switch (side) {
-	case 0:
-	    from.x = u0; from.y = v0;
-	    to.x   = u1; to.y   = v0;
-	    break;
-	case 1:
-	    from.x = u1; from.y = v0;
-	    to.x   = u1; to.y   = v1;
-	    break;
-	case 2:
-	    from.x = u1; from.y = v1;
-	    to.x   = u0; to.y   = v1;
-	    break;
-	case 3:
-	    from.x = u0; from.y = v1;
-	    to.x   = u0; to.y   = v0;
-	    break;
-	default:
-	    return NULL;
-    }
-    ON_Curve* c2d = new ON_LineCurve(from, to);
-    c2d->SetDomain(0.0, 1.0);
-    return c2d;
-}
-
-
-int // return value not used?
-MakeTwistedCubeTrimmingLoop(ON_Brep& brep,
-			    ON_BrepFace& face,
-			    int UNUSED(v0), int UNUSED(v1), int UNUSED(v2), int UNUSED(v3), // indices of corner vertices
-			    int e0, int eo0, // edge index + orientation w.r.t surface trim
-			    int e1, int eo1,
-			    int e2, int eo2,
-			    int e3, int eo3)
-{
-    // get a reference to the surface
-    const ON_Surface& srf = *brep.m_S[face.m_si];
-
-    ON_BrepLoop& loop = brep.NewLoop(ON_BrepLoop::outer, face);
-
-    // create the trimming curves running counter-clockwise around the
-    // surface's domain, start at the south side
-    ON_Curve* c2;
-    int c2i, ei = 0, bRev3d = 0;
-    ON_2dPoint q;
-
-    // flags for isoparametric curves
-    ON_Surface::ISO iso = ON_Surface::not_iso;
-
-    for (int side = 0; side < 4; side++) {
-	// side: 0=south, 1=east, 2=north, 3=west
-	c2 = TwistedCubeTrimmingCurve(srf, side);
-	c2i = brep.m_C2.Count();
-	brep.m_C2.Append(c2);
-
-	switch (side) {
-	    case 0:
-		ei = e0;
-		bRev3d = (eo0 == -1);
-		iso = ON_Surface::S_iso;
-		break;
-	    case 1:
-		ei = e1;
-		bRev3d = (eo1 == -1);
-		iso = ON_Surface::E_iso;
-		break;
-	    case 2:
-		ei = e2;
-		bRev3d = (eo2 == -1);
-		iso = ON_Surface::N_iso;
-		break;
-	    case 3:
-		ei = e3;
-		bRev3d = (eo3 == -1);
-		iso = ON_Surface::W_iso;
-		break;
-	}
-
-	ON_BrepTrim& trim = brep.NewTrim(brep.m_E[ei], bRev3d, loop, c2i);
-	trim.m_iso = iso;
-
-	// the type gives metadata on the trim type in this case, "mated"
-	// means the trim is connected to an edge, is part of an
-	// outer/inner/slit loop, no other trim from the same edge is
-	// connected to the edge, and at least one trim from a different
-	// loop is connected to the edge
-	trim.m_type = ON_BrepTrim::mated; // i.e. this b-rep is closed, so
-	// all trims have mates
-
-	// not convinced these shouldn't be set with a member function
-	trim.m_tolerance[0] = 0.0; // exact
-	trim.m_tolerance[1] = 0.0; //
-    }
-    return loop.m_loop_index;
-}
-
 void
-MakeTwistedCubeFace(ON_Brep& brep,
-		    int surf,
-		    int orientation,
-		    int v0, int v1, int v2, int v3, // the indices of corner vertices
-		    int e0, int eo0, // edge index + orientation
-		    int e1, int eo1,
-		    int e2, int eo2,
-		    int e3, int eo3)
-{
-    ON_BrepFace& face = brep.NewFace(surf);
-    MakeTwistedCubeTrimmingLoop(brep,
-				face,
-				v0, v1, v2, v3,
-				e0, eo0,
-				e1, eo1,
-				e2, eo2,
-				e3, eo3);
-    // should the normal be reversed?
-    face.m_bRev = (orientation == -1);
-}
-
-void
 MakeTwistedCubeFaces(ON_Brep& brep)
 {
     MakeTwistedCubeFace(brep,
@@ -405,25 +230,9 @@
     return brep;
 }
 
-void
-printPoints(struct rt_brep_internal* bi)
-{
-    ON_TextLog tl(stdout);
-    ON_Brep* brep = bi->brep;
-    if (brep) {
-	const int count = brep->m_V.Count();
-	for (int i = 0; i < count; i++) {
-	    ON_BrepVertex& bv = brep->m_V[i];
-	    bv.Dump(tl);
-	}
-    } else {
-	bu_log("brep was NULL!\n");
-    }
 }
 
-}
 
-
 static void
 printusage(void) {
     fprintf(stderr,"Usage: brep_cube (takes no arguments)\n");
@@ -495,11 +304,12 @@
     return 0;
 }
 
-
 #else /* !OBJ_BREP */
 
+#include "bu.h"
+
 int
-main(int argc, char *argv[])
+main(int UNUSED(argc), char *UNUSED(argv[]))
 {
     bu_log("ERROR: Boundary Representation object support is not available with\n"
 	   "       this compilation of BRL-CAD.\n");
Index: src/proc-db/brep_simple.cpp
===================================================================
--- src/proc-db/brep_simple.cpp	(revision 59234)
+++ src/proc-db/brep_simple.cpp	(working copy)
@@ -54,6 +54,8 @@
 /* without OBJ_BREP, this entire procedural example is disabled */
 #ifdef OBJ_BREP
 
+#include "twistedcube.h"
+
 #include "bio.h"
 
 #ifdef __cplusplus
@@ -83,25 +85,7 @@
     ABCD, BEHC, EFGH, FADG, FEBA, DCHG
 };
 
-ON_Curve*
-TwistedCubeEdgeCurve(const ON_3dPoint& from, const ON_3dPoint& to)
-{
-    // creates a 3d line segment to be used as a 3d curve in an ON_Brep
-    ON_Curve* c3d = new ON_LineCurve(from, to);
-    c3d->SetDomain(0.0, 1.0); // XXX is this UV bounds?
-    return c3d;
-}
-
 void
-MakeTwistedCubeEdge(ON_Brep& brep, int from, int to, int curve)
-{
-    ON_BrepVertex& v0 = brep.m_V[from];
-    ON_BrepVertex& v1 = brep.m_V[to];
-    ON_BrepEdge& edge = brep.NewEdge(v0, v1, curve);
-    edge.m_tolerance = 0.0; // exact!
-}
-
-void
 MakeTwistedCubeEdges(ON_Brep& brep)
 {
     MakeTwistedCubeEdge(brep, A, B, AB);
@@ -118,165 +102,7 @@
     MakeTwistedCubeEdge(brep, D, G, DG);
 }
 
-ON_Surface*
-TwistedCubeSideSurface(const ON_3dPoint& SW, const ON_3dPoint& SE, const ON_3dPoint& NE, const ON_3dPoint& NW)
-{
-    ON_NurbsSurface* pNurbsSurface = new ON_NurbsSurface(3, // dimension
-							 0, // not rational
-							 2, // u order
-							 2, // v order,
-							 2, // number of control vertices in u
-							 2 // number of control verts in v
-	);
-    pNurbsSurface->SetCV(0, 0, SW);
-    pNurbsSurface->SetCV(1, 0, SE);
-    pNurbsSurface->SetCV(1, 1, NE);
-    pNurbsSurface->SetCV(0, 1, NW);
-    // u knots
-    pNurbsSurface->SetKnot(0, 0, 0.0);
-    pNurbsSurface->SetKnot(0, 1, 1.0);
-    // v knots
-    pNurbsSurface->SetKnot(1, 0, 0.0);
-    pNurbsSurface->SetKnot(1, 1, 1.0);
-
-    return pNurbsSurface;
-}
-
-ON_Curve*
-TwistedCubeTrimmingCurve(const ON_Surface& s,
-			 int side // 0 = SW to SE, 1 = SE to NE, 2 = NE to NW, 3 = NW, SW
-    )
-{
-    // a trimming curve is a 2d curve whose image lies in the surface's
-    // domain. The "active" portion of the surface is to the left of the
-    // trimming curve (looking down the orientation of the curve). An
-    // outer trimming loop consists of a simple closed curve running
-    // counter-clockwise around the region it trims
-
-    ON_2dPoint from, to;
-    double u0, u1, v0, v1;
-    s.GetDomain(0, &u0, &u1);
-    s.GetDomain(1, &v0, &v1);
-
-    switch (side) {
-	case 0:
-	    from.x = u0; from.y = v0;
-	    to.x   = u1; to.y   = v0;
-	    break;
-	case 1:
-	    from.x = u1; from.y = v0;
-	    to.x   = u1; to.y   = v1;
-	    break;
-	case 2:
-	    from.x = u1; from.y = v1;
-	    to.x   = u0; to.y   = v1;
-	    break;
-	case 3:
-	    from.x = u0; from.y = v1;
-	    to.x   = u0; to.y   = v0;
-	    break;
-	default:
-	    return NULL;
-    }
-    ON_Curve* c2d = new ON_LineCurve(from, to);
-    c2d->SetDomain(0.0, 1.0);
-    return c2d;
-}
-
-
-int // return value not used?
-MakeTwistedCubeTrimmingLoop(ON_Brep& brep,
-			    ON_BrepFace& face,
-			    int UNUSED(v0), int UNUSED(v1), int UNUSED(v2), int UNUSED(v3), // indices of corner vertices
-			    int e0, int eo0, // edge index + orientation w.r.t surface trim
-			    int e1, int eo1,
-			    int e2, int eo2,
-			    int e3, int eo3)
-{
-    // get a reference to the surface
-    const ON_Surface& srf = *brep.m_S[face.m_si];
-
-    ON_BrepLoop& loop = brep.NewLoop(ON_BrepLoop::outer, face);
-
-    // create the trimming curves running counter-clockwise around the
-    // surface's domain, start at the south side
-    ON_Curve* c2;
-    int c2i, ei = 0, bRev3d = 0;
-    ON_2dPoint q;
-
-    // flags for isoparametric curves
-    ON_Surface::ISO iso = ON_Surface::not_iso;
-
-    for (int side = 0; side < 4; side++) {
-	// side: 0=south, 1=east, 2=north, 3=west
-	c2 = TwistedCubeTrimmingCurve(srf, side);
-	c2i = brep.m_C2.Count();
-	brep.m_C2.Append(c2);
-
-	switch (side) {
-	    case 0:
-		ei = e0;
-		bRev3d = (eo0 == -1);
-		iso = ON_Surface::S_iso;
-		break;
-	    case 1:
-		ei = e1;
-		bRev3d = (eo1 == -1);
-		iso = ON_Surface::E_iso;
-		break;
-	    case 2:
-		ei = e2;
-		bRev3d = (eo2 == -1);
-		iso = ON_Surface::N_iso;
-		break;
-	    case 3:
-		ei = e3;
-		bRev3d = (eo3 == -1);
-		iso = ON_Surface::W_iso;
-		break;
-	}
-
-	ON_BrepTrim& trim = brep.NewTrim(brep.m_E[ei], bRev3d, loop, c2i);
-	trim.m_iso = iso;
-
-	// the type gives metadata on the trim type in this case, "mated"
-	// means the trim is connected to an edge, is part of an
-	// outer/inner/slit loop, no other trim from the same loop is
-	// connected to the edge, and at least one trim from a different
-	// loop is connected to the edge
-	trim.m_type = ON_BrepTrim::mated; // i.e. this b-rep is closed, so
-	// all trims have mates
-
-	// not convinced these shouldn't be set with a member function
-	trim.m_tolerance[0] = 0.0; // exact
-	trim.m_tolerance[1] = 0.0; //
-    }
-    return loop.m_loop_index;
-}
-
 void
-MakeTwistedCubeFace(ON_Brep& brep,
-		    int surf,
-		    int orientation,
-		    int v0, int v1, int v2, int v3, // the indices of corner vertices
-		    int e0, int eo0, // edge index + orientation
-		    int e1, int eo1,
-		    int e2, int eo2,
-		    int e3, int eo3)
-{
-    ON_BrepFace& face = brep.NewFace(surf);
-    MakeTwistedCubeTrimmingLoop(brep,
-				face,
-				v0, v1, v2, v3,
-				e0, eo0,
-				e1, eo1,
-				e2, eo2,
-				e3, eo3);
-    // should the normal be reversed?
-    face.m_bRev = (orientation == -1);
-}
-
-void
 MakeTwistedCubeFaces(ON_Brep& brep)
 {
     // The direction of each edge was determined when the edge was
@@ -410,22 +236,6 @@
     return brep;
 }
 
-void
-printPoints(struct rt_brep_internal* bi)
-{
-    ON_TextLog tl(stdout);
-    ON_Brep* brep = bi->brep;
-    if (brep) {
-	const int count = brep->m_V.Count();
-	for (int i = 0; i < count; i++) {
-	    ON_BrepVertex& bv = brep->m_V[i];
-	    bv.Dump(tl);
-	}
-    } else {
-	fprintf(stderr, "brep was NULL!\n");
-    }
-}
-
 } /* end namespace */
 
 
Index: src/proc-db/surfaceintersect.cpp
===================================================================
--- src/proc-db/surfaceintersect.cpp	(revision 59234)
+++ src/proc-db/surfaceintersect.cpp	(working copy)
@@ -996,27 +996,7 @@
 using namespace si;
 
 
-ON_Curve*
-TwistedCubeEdgeCurve(const ON_3dPoint& from, const ON_3dPoint& to)
-{
-    // creates a 3d line segment to be used as a 3d curve in an ON_Brep
-    ON_Curve* c3d = new ON_LineCurve(from, to);
-    c3d->SetDomain(0.0, 1.0); // XXX is this UV bounds?
-    return c3d;
-}
-
-
 void
-MakeTwistedCubeEdge(ON_Brep& brep, int from, int to, int curve)
-{
-    ON_BrepVertex& v0 = brep.m_V[from];
-    ON_BrepVertex& v1 = brep.m_V[to];
-    ON_BrepEdge& edge = brep.NewEdge(v0, v1, curve);
-    edge.m_tolerance = 0.0; // exact!
-}
-
-
-void
 MakeTwistedCubeEdges1(ON_Brep& brep)
 {
     MakeTwistedCubeEdge(brep, A, B, AB);
@@ -1036,168 +1016,7 @@
 }
 
 
-ON_Surface*
-TwistedCubeSideSurface(const ON_3dPoint& SW, const ON_3dPoint& SE, const ON_3dPoint& NE, const ON_3dPoint& NW)
-{
-    ON_NurbsSurface* pNurbsSurface = new ON_NurbsSurface(3, // dimension
-							 0, // not rational
-							 2, // u order
-							 2, // v order,
-							 2, // number of control vertices in u
-							 2 // number of control verts in v
-	);
-    pNurbsSurface->SetCV(0, 0, SW);
-    pNurbsSurface->SetCV(1, 0, SE);
-    pNurbsSurface->SetCV(1, 1, NE);
-    pNurbsSurface->SetCV(0, 1, NW);
-    // u knots
-    pNurbsSurface->SetKnot(0, 0, 0.0);
-    pNurbsSurface->SetKnot(0, 1, 1.0);
-    // v knots
-    pNurbsSurface->SetKnot(1, 0, 0.0);
-    pNurbsSurface->SetKnot(1, 1, 1.0);
-
-    return pNurbsSurface;
-}
-
-
-ON_Curve*
-TwistedCubeTrimmingCurve(const ON_Surface& s,
-			 int side // 0 = SW to SE, 1 = SE to NE, 2 = NE to NW, 3 = NW, SW
-    )
-{
-    // a trimming curve is a 2d curve whose image lies in the surface's
-    // domain. The "active" portion of the surface is to the left of the
-    // trimming curve (looking down the orientation of the curve). An
-    // outer trimming loop consists of a simple closed curve running
-    // counter-clockwise around the region it trims
-
-    ON_2dPoint from, to;
-    double u0, u1, v0, v1;
-    s.GetDomain(0, &u0, &u1);
-    s.GetDomain(1, &v0, &v1);
-
-    switch (side) {
-	case 0:
-	    from.x = u0; from.y = v0;
-	    to.x   = u1; to.y   = v0;
-	    break;
-	case 1:
-	    from.x = u1; from.y = v0;
-	    to.x   = u1; to.y   = v1;
-	    break;
-	case 2:
-	    from.x = u1; from.y = v1;
-	    to.x   = u0; to.y   = v1;
-	    break;
-	case 3:
-	    from.x = u0; from.y = v1;
-	    to.x   = u0; to.y   = v0;
-	    break;
-	default:
-	    return NULL;
-    }
-    ON_Curve* c2d = new ON_LineCurve(from, to);
-    c2d->SetDomain(0.0, 1.0);
-    return c2d;
-}
-
-
-int // return value not used?
-MakeTwistedCubeTrimmingLoop(ON_Brep& brep,
-			    ON_BrepFace& face,
-			    int UNUSED(v0), int UNUSED(v1), int UNUSED(v2), int UNUSED(v3), // indices of corner vertices
-			    int e0, int eo0, // edge index + orientation w.r.t surface trim
-			    int e1, int eo1,
-			    int e2, int eo2,
-			    int e3, int eo3)
-{
-    // get a reference to the surface
-    const ON_Surface& srf = *brep.m_S[face.m_si];
-
-    ON_BrepLoop& loop = brep.NewLoop(ON_BrepLoop::outer, face);
-
-    // create the trimming curves running counter-clockwise around the
-    // surface's domain, start at the south side
-    ON_Curve* c2;
-    int c2i, ei = 0, bRev3d = 0;
-    ON_2dPoint q;
-
-    // flags for isoparametric curves
-    ON_Surface::ISO iso = ON_Surface::not_iso;
-
-    for (int side = 0; side < 4; side++) {
-	// side: 0=south, 1=east, 2=north, 3=west
-	c2 = TwistedCubeTrimmingCurve(srf, side);
-	c2i = brep.m_C2.Count();
-	brep.m_C2.Append(c2);
-
-	switch (side) {
-	    case 0:
-		ei = e0;
-		bRev3d = (eo0 == -1);
-		iso = ON_Surface::S_iso;
-		break;
-	    case 1:
-		ei = e1;
-		bRev3d = (eo1 == -1);
-		iso = ON_Surface::E_iso;
-		break;
-	    case 2:
-		ei = e2;
-		bRev3d = (eo2 == -1);
-		iso = ON_Surface::N_iso;
-		break;
-	    case 3:
-		ei = e3;
-		bRev3d = (eo3 == -1);
-		iso = ON_Surface::W_iso;
-		break;
-	}
-
-	ON_BrepTrim& trim = brep.NewTrim(brep.m_E[ei], bRev3d, loop, c2i);
-	trim.m_iso = iso;
-
-	// the type gives metadata on the trim type in this case, "mated"
-	// means the trim is connected to an edge, is part of an
-	// outer/inner/slit loop, no other trim from the same edge is
-	// connected to the edge, and at least one trim from a different
-	// loop is connected to the edge
-	trim.m_type = ON_BrepTrim::mated; // i.e. this b-rep is closed, so
-	// all trims have mates
-
-	// not convinced these shouldn't be set with a member function
-	trim.m_tolerance[0] = 0.0; // exact
-	trim.m_tolerance[1] = 0.0; //
-    }
-    return loop.m_loop_index;
-}
-
-
 void
-MakeTwistedCubeFace(ON_Brep& brep,
-		    int surf,
-		    int orientation,
-		    int v0, int v1, int v2, int v3, // the indices of corner vertices
-		    int e0, int eo0, // edge index + orientation
-		    int e1, int eo1,
-		    int e2, int eo2,
-		    int e3, int eo3)
-{
-    ON_BrepFace& face = brep.NewFace(surf);
-    MakeTwistedCubeTrimmingLoop(brep,
-				face,
-				v0, v1, v2, v3,
-				e0, eo0,
-				e1, eo1,
-				e2, eo2,
-				e3, eo3);
-    // should the normal be reversed?
-    face.m_bRev = (orientation == -1);
-}
-
-
-void
 MakeTwistedCubeFaces1(ON_Brep& brep)
 {
     MakeTwistedCubeFace(brep,
@@ -1319,24 +1138,6 @@
 }
 
 
-void
-printPoints(struct rt_brep_internal* bi)
-{
-    ON_TextLog tl(stdout);
-    ON_Brep* brep = bi->brep;
-
-    if (brep) {
-	const int count = brep->m_V.Count();
-	for (int i = 0; i < count; i++) {
-	    ON_BrepVertex& bv = brep->m_V[i];
-	    bv.Dump(tl);
-	}
-    } else {
-	bu_log("brep was NULL!\n");
-    }
-}
-
-
 int
 main()
 {
Index: src/proc-db/surfaceintersect.h
===================================================================
--- src/proc-db/surfaceintersect.h	(revision 59234)
+++ src/proc-db/surfaceintersect.h	(working copy)
@@ -31,6 +31,7 @@
 #include "bu.h"
 #include "vmath.h"
 #include "opennurbs_array.h"
+#include "twistedcube.h"
 
 
 /**
Index: src/proc-db/twistedcube.cpp
===================================================================
--- src/proc-db/twistedcube.cpp	(revision 0)
+++ src/proc-db/twistedcube.cpp	(working copy)
@@ -0,0 +1,222 @@
+/*                    T W I S T E D C U B E . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 2004-2013 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file twistedcube.cpp
+ *
+ * Implementation of TwistedCube functions used in brep_simple.cpp,
+ * brep_cube.cpp, and surfaceintersect.cpp
+ *
+ */
+
+#include "twistedcube.h"
+
+ON_Curve*
+TwistedCubeEdgeCurve(const ON_3dPoint& from, const ON_3dPoint& to)
+{
+    // creates a 3d line segment to be used as a 3d curve in an ON_Brep
+    ON_Curve* c3d = new ON_LineCurve(from, to);
+    c3d->SetDomain(0.0, 1.0); // XXX is this UV bounds?
+    return c3d;
+}
+
+void
+MakeTwistedCubeEdge(ON_Brep& brep, int from, int to, int curve)
+{
+    ON_BrepVertex& v0 = brep.m_V[from];
+    ON_BrepVertex& v1 = brep.m_V[to];
+    ON_BrepEdge& edge = brep.NewEdge(v0, v1, curve);
+    edge.m_tolerance = 0.0; // exact!
+}
+
+ON_Surface*
+TwistedCubeSideSurface(const ON_3dPoint& SW, const ON_3dPoint& SE, const ON_3dPoint& NE, const ON_3dPoint& NW)
+{
+    ON_NurbsSurface* pNurbsSurface = new ON_NurbsSurface(3, // dimension
+							 0, // not rational
+							 2, // u order
+							 2, // v order,
+							 2, // number of control vertices in u
+							 2 // number of control verts in v
+	);
+    pNurbsSurface->SetCV(0, 0, SW);
+    pNurbsSurface->SetCV(1, 0, SE);
+    pNurbsSurface->SetCV(1, 1, NE);
+    pNurbsSurface->SetCV(0, 1, NW);
+    // u knots
+    pNurbsSurface->SetKnot(0, 0, 0.0);
+    pNurbsSurface->SetKnot(0, 1, 1.0);
+    // v knots
+    pNurbsSurface->SetKnot(1, 0, 0.0);
+    pNurbsSurface->SetKnot(1, 1, 1.0);
+
+    return pNurbsSurface;
+}
+
+
+ON_Curve*
+TwistedCubeTrimmingCurve(const ON_Surface& s,
+			 int side // 0 = SW to SE, 1 = SE to NE, 2 = NE to NW, 3 = NW, SW
+    )
+{
+    // a trimming curve is a 2d curve whose image lies in the surface's
+    // domain. The "active" portion of the surface is to the left of the
+    // trimming curve (looking down the orientation of the curve). An
+    // outer trimming loop consists of a simple closed curve running
+    // counter-clockwise around the region it trims
+
+    ON_2dPoint from, to;
+    double u0, u1, v0, v1;
+    s.GetDomain(0, &u0, &u1);
+    s.GetDomain(1, &v0, &v1);
+
+    switch (side) {
+	case 0:
+	    from.x = u0; from.y = v0;
+	    to.x   = u1; to.y   = v0;
+	    break;
+	case 1:
+	    from.x = u1; from.y = v0;
+	    to.x   = u1; to.y   = v1;
+	    break;
+	case 2:
+	    from.x = u1; from.y = v1;
+	    to.x   = u0; to.y   = v1;
+	    break;
+	case 3:
+	    from.x = u0; from.y = v1;
+	    to.x   = u0; to.y   = v0;
+	    break;
+	default:
+	    return NULL;
+    }
+    ON_Curve* c2d = new ON_LineCurve(from, to);
+    c2d->SetDomain(0.0, 1.0);
+    return c2d;
+}
+
+
+int // return value not used?
+MakeTwistedCubeTrimmingLoop(ON_Brep& brep,
+			    ON_BrepFace& face,
+			    int UNUSED(v0), int UNUSED(v1), int UNUSED(v2), int UNUSED(v3), // indices of corner vertices
+			    int e0, int eo0, // edge index + orientation w.r.t surface trim
+			    int e1, int eo1,
+			    int e2, int eo2,
+			    int e3, int eo3)
+{
+    // get a reference to the surface
+    const ON_Surface& srf = *brep.m_S[face.m_si];
+
+    ON_BrepLoop& loop = brep.NewLoop(ON_BrepLoop::outer, face);
+
+    // create the trimming curves running counter-clockwise around the
+    // surface's domain, start at the south side
+    ON_Curve* c2;
+    int c2i, ei = 0, bRev3d = 0;
+    ON_2dPoint q;
+
+    // flags for isoparametric curves
+    ON_Surface::ISO iso = ON_Surface::not_iso;
+
+    for (int side = 0; side < 4; side++) {
+	// side: 0=south, 1=east, 2=north, 3=west
+	c2 = TwistedCubeTrimmingCurve(srf, side);
+	c2i = brep.m_C2.Count();
+	brep.m_C2.Append(c2);
+
+	switch (side) {
+	    case 0:
+		ei = e0;
+		bRev3d = (eo0 == -1);
+		iso = ON_Surface::S_iso;
+		break;
+	    case 1:
+		ei = e1;
+		bRev3d = (eo1 == -1);
+		iso = ON_Surface::E_iso;
+		break;
+	    case 2:
+		ei = e2;
+		bRev3d = (eo2 == -1);
+		iso = ON_Surface::N_iso;
+		break;
+	    case 3:
+		ei = e3;
+		bRev3d = (eo3 == -1);
+		iso = ON_Surface::W_iso;
+		break;
+	}
+
+	ON_BrepTrim& trim = brep.NewTrim(brep.m_E[ei], bRev3d, loop, c2i);
+	trim.m_iso = iso;
+
+	// the type gives metadata on the trim type in this case, "mated"
+	// means the trim is connected to an edge, is part of an
+	// outer/inner/slit loop, no other trim from the same edge is
+	// connected to the edge, and at least one trim from a different
+	// loop is connected to the edge
+	trim.m_type = ON_BrepTrim::mated; // i.e. this b-rep is closed, so
+	// all trims have mates
+
+	// not convinced these shouldn't be set with a member function
+	trim.m_tolerance[0] = 0.0; // exact
+	trim.m_tolerance[1] = 0.0; //
+    }
+    return loop.m_loop_index;
+}
+
+void
+MakeTwistedCubeFace(ON_Brep& brep,
+		    int surf,
+		    int orientation,
+		    int v0, int v1, int v2, int v3, // the indices of corner vertices
+		    int e0, int eo0, // edge index + orientation
+		    int e1, int eo1,
+		    int e2, int eo2,
+		    int e3, int eo3)
+{
+    ON_BrepFace& face = brep.NewFace(surf);
+    MakeTwistedCubeTrimmingLoop(brep,
+				face,
+				v0, v1, v2, v3,
+				e0, eo0,
+				e1, eo1,
+				e2, eo2,
+				e3, eo3);
+    // should the normal be reversed?
+    face.m_bRev = (orientation == -1);
+}
+
+
+void
+printPoints(struct rt_brep_internal* bi)
+{
+    ON_TextLog tl(stdout);
+    ON_Brep* brep = bi->brep;
+
+    if (brep) {
+	const int count = brep->m_V.Count();
+	for (int i = 0; i < count; i++) {
+	    ON_BrepVertex& bv = brep->m_V[i];
+	    bv.Dump(tl);
+	}
+    } else {
+	bu_log("brep was NULL!\n");
+    }
+}
Index: src/proc-db/twistedcube.h
===================================================================
--- src/proc-db/twistedcube.h	(revision 0)
+++ src/proc-db/twistedcube.h	(working copy)
@@ -0,0 +1,71 @@
+/*                   T W I S T E D C U B E . H
+ * BRL-CAD
+ *
+ * Copyright (c) 2013 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file twistedcube_private.h
+ *
+ * Private header for TwistedCube functions used in brep_simple.cpp,
+ * brep_cube.cpp, and surfaceintersect.cpp
+ *
+ */
+
+#ifndef PROC_DB_TWISTEDCUBE_H
+#define PROC_DB_TWISTEDCUBE_H
+
+#include "common.h"
+#include "wdb.h"
+
+extern ON_Curve* TwistedCubeEdgeCurve(const ON_3dPoint& from, const ON_3dPoint& to);
+
+extern void MakeTwistedCubeEdge(ON_Brep& brep, int from, int to, int curve);
+
+extern ON_Surface* TwistedCubeSideSurface(const ON_3dPoint& SW, const ON_3dPoint& SE, const ON_3dPoint& NE, const ON_3dPoint& NW);
+
+extern ON_Curve* TwistedCubeTrimmingCurve(const ON_Surface& s, int side);
+
+extern int MakeTwistedCubeTrimmingLoop(ON_Brep& brep,
+                                       ON_BrepFace& face,
+                                       int UNUSED(v0), int UNUSED(v1), int UNUSED(v2), int UNUSED(v3), // indices of corner vertices
+                                       int e0, int eo0, // edge index + orientation w.r.t surface trim
+                                       int e1, int eo1,
+                                       int e2, int eo2,
+                                       int e3, int eo3);
+
+extern void MakeTwistedCubeFace(ON_Brep& brep,
+                                int surf,
+                                int orientation,
+                                int v0, int v1, int v2, int v3, // the indices of corner vertices
+                                int e0, int eo0, // edge index + orientation
+                                int e1, int eo1,
+                                int e2, int eo2,
+                                int e3, int eo3);
+
+extern void printPoints(struct rt_brep_internal* bi);
+
+#endif /* PROC_DB_TWISTEDCUBE_H */
+
+/** @} */
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
