Index: src/embeddedLua/CMakeLists.txt
===================================================================
--- src/embeddedLua/CMakeLists.txt	(revision 70619)
+++ src/embeddedLua/CMakeLists.txt	(working copy)
@@ -39,6 +39,7 @@
     embeddedlua.cpp
     initbrlcad.cpp
     luadatabase.cpp
+    luahalfspace.cpp
     writestring.cpp
     ../other/lua/src/lapi.c
     ../other/lua/src/lcode.c
Index: src/embeddedLua/initbrlcad.cpp
===================================================================
--- src/embeddedLua/initbrlcad.cpp	(revision 70619)
+++ src/embeddedLua/initbrlcad.cpp	(working copy)
@@ -29,6 +29,7 @@
  */
 
 #include "luadatabase.h"
+#include "luahalfspace.h"
 #include "initbrlcad.h"
 
 
@@ -38,4 +39,5 @@
     BRLCAD::Database& database
 ) {
     InitDatabase(luaState, database);
+    InitHalfspace(luaState);
 }
Index: src/embeddedLua/luahalfspace.cpp
===================================================================
--- src/embeddedLua/luahalfspace.cpp	(nonexistent)
+++ src/embeddedLua/luahalfspace.cpp	(working copy)
@@ -0,0 +1,179 @@
+/*                  L U A H A L F S P A C E . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 2018 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+/** @file luahalfspace.cpp
+ *
+ *  BRL-CAD embedded lua script:
+ *      BRLCAD::Halfspace functions
+ */
+
+#include <embeddedlua.h>
+
+#include "luahalfspace.h"
+
+
+using namespace BRLCAD;
+
+
+static int Normal
+(
+    lua_State* luaState
+) {
+    Halfspace** pHalfspace = (Halfspace**)luaL_checkudata(luaState, 1, "Halfspace");
+    Vector3D    normal     = (*pHalfspace)->Normal();
+
+    lua_pushnumber(luaState, normal.coordinates[0]);
+    lua_pushnumber(luaState, normal.coordinates[1]);
+    lua_pushnumber(luaState, normal.coordinates[2]);
+
+    return 3;
+}
+
+
+static int SetNormal
+(
+    lua_State* luaState
+) {
+    Halfspace**  pHalfspace = (Halfspace**)luaL_checkudata(luaState, 1, "Halfspace");
+    const double x          = luaL_checknumber(luaState, -3);
+    const double y          = luaL_checknumber(luaState, -2);
+    const double z          = luaL_checknumber(luaState, -1);
+
+    (*pHalfspace)->SetNormal(Vector3D(x, y, z));
+
+    return 0;
+}
+
+
+static int DistanceFromOrigin
+(
+    lua_State* luaState
+) {
+    Halfspace**  pHalfspace = (Halfspace**)luaL_checkudata(luaState, 1, "Halfspace");
+
+    lua_pushnumber(luaState, (*pHalfspace)->DistanceFromOrigin());
+
+    return 1;
+}
+
+
+static int SetDistanceFromOrigin
+(
+    lua_State* luaState
+) {
+    Halfspace**  pHalfspace = (Halfspace**)luaL_checkudata(luaState, 1, "Halfspace");
+    const double distance   = luaL_checknumber(luaState, -1);
+
+    (*pHalfspace)->SetDistanceFromOrigin(distance);
+
+    return 0;
+}
+
+
+static int ClassName
+(
+    lua_State* luaState
+) {
+    Halfspace**  pHalfspace = (Halfspace**)luaL_checkudata(luaState, 1, "Halfspace");
+
+    lua_pushstring(luaState, (*pHalfspace)->ClassName());
+
+    return 1;
+}
+
+
+static int Type
+(
+    lua_State* luaState
+) {
+    Halfspace**  pHalfspace = (Halfspace**)luaL_checkudata(luaState, 1, "Halfspace");
+
+    lua_pushstring(luaState, (*pHalfspace)->Type());
+
+    return 1;
+}
+
+
+static int IsValid
+(
+    lua_State* luaState
+) {
+    Halfspace**  pHalfspace = (Halfspace**)luaL_checkudata(luaState, 1, "Halfspace");
+
+    lua_pushboolean(luaState, (*pHalfspace)->IsValid());
+
+    return 1;
+}
+
+
+void InitHalfspace
+(
+    lua_State* luaState
+) {
+    lua_newtable(luaState);
+    int methodtable = lua_gettop(luaState);
+    luaL_newmetatable(luaState, "Halfspace");
+    int metatable   = lua_gettop(luaState);
+
+    lua_pushliteral(luaState, "__metatable");
+    lua_pushvalue(luaState, methodtable);
+    lua_settable(luaState, metatable);
+
+    lua_pushliteral(luaState, "__index");
+    lua_pushvalue(luaState, methodtable);
+    lua_settable(luaState, metatable);
+
+    lua_pop(luaState, 1);
+
+    lua_pushcfunction(luaState, Normal);
+    lua_setfield(luaState, -2, "Normal");
+
+    lua_pushcfunction(luaState, SetNormal);
+    lua_setfield(luaState, -2, "SetNormal");
+
+    lua_pushcfunction(luaState, DistanceFromOrigin);
+    lua_setfield(luaState, -2, "DistanceFromOrigin");
+
+    lua_pushcfunction(luaState, SetDistanceFromOrigin);
+    lua_setfield(luaState, -2, "SetDistanceFromOrigin");
+
+    lua_pushcfunction(luaState, ClassName);
+    lua_setfield(luaState, -2, "ClassName");
+
+    lua_pushcfunction(luaState, Type);
+    lua_setfield(luaState, -2, "Type");
+
+    lua_pushcfunction(luaState, IsValid);
+    lua_setfield(luaState, -2, "IsValid");
+
+    lua_pop(luaState, 1);
+
+    Halfspace** pHalfspace = static_cast<Halfspace**>(lua_newuserdata(luaState, sizeof(Halfspace*)));
+    *pHalfspace = new Halfspace();
+
+    luaL_getmetatable(luaState, "Halfspace");
+    lua_setmetatable(luaState, -2);
+
+    lua_setglobal(luaState, "halfspace");
+}
Index: src/embeddedLua/luahalfspace.h
===================================================================
--- src/embeddedLua/luahalfspace.h	(nonexistent)
+++ src/embeddedLua/luahalfspace.h	(working copy)
@@ -0,0 +1,45 @@
+/*                  L U A H A L F S P A C E . H
+ * BRL-CAD
+ *
+ * Copyright (c) 2018 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+/** @file luahalfspace.h
+ *
+ *  BRL-CAD embedded lua script:
+ *      BRLCAD::Halfspace functions
+ */
+
+#ifndef LUAHALFSPACE_INCLUDED
+#define LUAHALFSPACE_INCLUDED
+
+#include "lua.hpp"
+
+#include "brlcad/Halfspace.h"
+
+
+void InitHalfspace
+(
+    lua_State* luaState
+);
+
+
+#endif // LUAHALFSPACE_INCLUDED
