Index: include/bn.h
===================================================================
--- include/bn.h	(Revision 59269)
+++ include/bn.h	(Arbeitskopie)
@@ -4653,6 +4653,19 @@
 BN_EXPORT extern int bn_polygon_mk_pts_planes(size_t *npts, point_t **pts, size_t neqs, const plane_t *eqs);
 
 
+/**
+ * sort an array of point_ts, building a convex polygon, counter-clockwise
+ *
+ *@param[in] npts Number of points, pts contains
+ *@param pts Array of point_ts, building a convex polygon. Duplicated points
+ *aren't allowed. The points in the array will be sorted counter-clockwise.
+ *@param[in] cmp Plane equation of the polygon
+ *
+ *@return 0 if calculation was succesful
+ *@return 1 if calculation failed, e.g. because pts is a NULL-pointer
+ */
+BN_EXPORT extern int bn_polygon_sort_ccw(size_t npts, point_t *pts, plane_t cmp);
+
 #endif /* BN_H */
 
 /** @} */
Index: src/libbn/polygon.c
===================================================================
--- src/libbn/polygon.c	(Revision 59269)
+++ src/libbn/polygon.c	(Arbeitskopie)
@@ -167,6 +167,25 @@
 }
 
 
+static int
+bn_sort_helper_ccw(const void *x, const void *y, void *cmp)
+{
+    vect_t tmp;
+    VCROSS(tmp, ((fastf_t *)x), ((fastf_t *)y));
+    return VDOT(*((point_t *)cmp), tmp);
+}
+
+
+int
+bn_polygon_sort_ccw(size_t npts, point_t *pts, plane_t cmp)
+{
+    if (!pts || npts < 3)
+	return 1;
+    bu_sort(pts, npts, sizeof(point_t), bn_sort_helper_ccw, &cmp);
+    return 0;
+}
+
+
 /*
  * Local Variables:
  * mode: C
Index: src/libged/analyze.c
===================================================================
--- src/libged/analyze.c	(Revision 59269)
+++ src/libged/analyze.c	(Arbeitskopie)
@@ -712,17 +712,6 @@
 }
 
 
-/* qsort helper function, used to sort points into
- * counter-clockwise order */
-HIDDEN int
-ccw(const void *x, const void *y, void *cmp)
-{
-    vect_t tmp;
-    VCROSS(tmp, ((fastf_t *)x), ((fastf_t *)y));
-    return VDOT(*((point_t *)cmp), tmp);
-}
-
-
 /**
  * A N A L Y Z E _ P O L Y _ F A C E
  *
@@ -746,7 +735,7 @@
     findang(angles, face->plane_eqn);
 
     /* sort points */
-    bu_sort(face->pts, face->npts, sizeof(point_t), ccw, &face->plane_eqn);
+    bn_polygon_sort_ccw(face->npts, face->pts, face->plane_eqn);
     bn_polygon_area(&face->area, face->npts, (const point_t *)face->pts);
 
     /* store face information for pretty printing */
Index: src/librt/primitives/arbn/arbn.c
===================================================================
--- src/librt/primitives/arbn/arbn.c	(Revision 59269)
+++ src/librt/primitives/arbn/arbn.c	(Arbeitskopie)
@@ -1334,17 +1334,6 @@
 };
 
 
-/* bu_sort helper function, used to sort points into
- * counter-clockwise order */
-HIDDEN int
-ccw(const void *x, const void *y, void *cmp)
-{
-    vect_t tmp;
-    VCROSS(tmp, ((fastf_t *)x), ((fastf_t *)y));
-    return VDOT(*((point_t *)cmp), tmp);
-}
-
-
 static void
 rt_arbn_faces_area(struct poly_face* faces, struct rt_arbn_internal* aip)
 {
@@ -1362,7 +1351,7 @@
     bn_polygon_mk_pts_planes(npts, tmp_pts, aip->neqn, (const plane_t *)eqs);
     for (i = 0; i < aip->neqn; i++) {
 	faces[i].npts = npts[i];
-    	bu_sort(faces[i].pts, faces[i].npts, sizeof(point_t), ccw, &faces[i].plane_eqn);
+    	bn_polygon_sort_ccw(faces[i].npts, faces[i].pts, faces[i].plane_eqn);
     	bn_polygon_area(&faces[i].area, faces[i].npts, (const point_t *)faces[i].pts);
     }
     bu_free((char *)tmp_pts, "rt_arbn_faces_area: tmp_pts");
Index: src/librt/primitives/bot/bot.c
===================================================================
--- src/librt/primitives/bot/bot.c	(Revision 59269)
+++ src/librt/primitives/bot/bot.c	(Arbeitskopie)
@@ -5276,17 +5276,6 @@
 }
 
 
-/* qsort helper function, used to sort points into
- * counter-clockwise order */
-HIDDEN int
-ccw_algo(const void *x, const void *y, void *cmp)
-{
-    vect_t tmp;
-    VCROSS(tmp, ((fastf_t *)x), ((fastf_t *)y));
-    return VDOT(*((point_t *)cmp), tmp);
-}
-
-
 void
 rt_bot_volume(fastf_t *volume, const struct rt_db_internal *ip)
 {
@@ -5338,7 +5327,7 @@
 	/* SURFACE AREA */
 
 	/* sort points */
-	bu_sort(face.pts, face.npts, sizeof(point_t), ccw_algo, &face.plane_eqn);
+	bn_polygon_sort_ccw(face.npts, face.pts, face.plane_eqn);
 	bn_polygon_area(&face.area, face.npts, (const point_t *)face.pts);
 
 	/* VOLUME */
Index: src/librt/primitives/nmg/nmg.c
===================================================================
--- src/librt/primitives/nmg/nmg.c	(Revision 59269)
+++ src/librt/primitives/nmg/nmg.c	(Arbeitskopie)
@@ -3107,17 +3107,6 @@
 }
 
 
-/* bu_sort helper function, used to sort points into
- * counter-clockwise order */
-HIDDEN int
-nmg_ccw(const void *x, const void *y, void *cmp)
-{
-    vect_t tmp;
-    VCROSS(tmp, ((fastf_t *)x), ((fastf_t *)y));
-    return VDOT(*((point_t *)cmp), tmp);
-}
-
-
 /* contains information used to analyze a polygonal face */
 struct poly_face
 {
@@ -3157,7 +3146,7 @@
     bn_polygon_mk_pts_planes(npts, tmp_pts, num_faces, (const plane_t *)eqs);
     for (i = 0; i < num_faces; i++) {
 	faces[i].npts = npts[i];
-	bu_sort(faces[i].pts, faces[i].npts, sizeof(point_t), nmg_ccw, &faces[i].plane_eqn);
+	bn_polygon_sort_ccw(faces[i].npts, faces[i].pts, faces[i].plane_eqn);
 	bn_polygon_area(&faces[i].area, faces[i].npts, (const point_t *)faces[i].pts);
     }
     bu_free((char *)tmp_pts, "rt_nmg_faces_area: tmp_pts");
