diff --git a/svggen/api/composables/GraphComposable.py b/svggen/api/composables/GraphComposable.py
index d8502d97522fad21a7e9ce33f2a10ed97131b4c9..8f38db70c5ef88087b8c6980a9f98eea7c50a0c1 100644
--- a/svggen/api/composables/GraphComposable.py
+++ b/svggen/api/composables/GraphComposable.py
@@ -88,8 +88,6 @@ class Graph(Composable, BaseGraph):
         from svggen.utils.tabs import BeamTabs, BeamTabDecoration, BeamSlotDecoration
         self.tabify(kw("tabFace", BeamTabs), kw("tabDecoration", BeamTabDecoration),
                     kw("slotFace", None), kw("slotDecoration", BeamSlotDecoration))
-        if kw("joint", None):
-            self.jointify(**kwargs)
         self.place()
 
     '''
diff --git a/svggen/api/composables/graph/Drawing.py b/svggen/api/composables/graph/Drawing.py
index b132363df129a9e6a4d514ad8133c55cd70815c3..0edf90154d6b210c3e4a0219c0fabd158c8d3c44 100644
--- a/svggen/api/composables/graph/Drawing.py
+++ b/svggen/api/composables/graph/Drawing.py
@@ -49,8 +49,6 @@ class Drawing:
                         angle = angles[1][0] - angles[0][0]
                     if angle == 0:
                         edge = Flat()
-                    elif e.edgeType is "BEND":
-                        edge = Flex(angle=angle)
                     else:
                         edge = Fold(angle=angle)
                 else:
diff --git a/svggen/api/composables/graph/Face.py b/svggen/api/composables/graph/Face.py
index 286183b8bc8334d9d42c5f20bb5f1fc085cc902e..d693661d6a0ca94e98ecbf953d2319b46616b58d 100644
--- a/svggen/api/composables/graph/Face.py
+++ b/svggen/api/composables/graph/Face.py
@@ -246,8 +246,7 @@ class Face(object):
     coords2D = self.get2DCoords()
     coords3D = self.get3DCoords()
 
-    # Follow all non-joints before joints
-    for (i, e) in sorted(enumerate(self.edges), key=lambda x : x[1].isJoint()):
+    for (i, e) in enumerate(self.edges):
       # XXX hack: don't follow small edges
       if e is None or e.isTab():
         continue
@@ -281,13 +280,10 @@ class Face(object):
 
         x = RotateXTo(ptb, pta)
 
-        if e.isJoint():
-            t2d = None
-        else:
-            r2d = np.eye(4)
-            r2d = np.dot(x, r2d)
-            r2d = np.dot(MoveOriginTo(pta), r2d)
-            t2d = np.dot(transform2D, r2d)
+        r2d = np.eye(4)
+        r2d = np.dot(x, r2d)
+        r2d = np.dot(MoveOriginTo(pta), r2d)
+        t2d = np.dot(transform2D, r2d)
 
         r3d = RotateX(np.deg2rad(a[0]+da[0]))
         r3d = np.dot(x, r3d)
@@ -297,17 +293,6 @@ class Face(object):
         f.place(e, t2d, t3d, facelists, flind)
         # end for faces.iteritems
 
-    for e in self.edges:
-        if e.isJoint():
-            index = self.edgeIndex(e.name)
-            # print "Jointing ", e.name, "on face", self.name, index
-            newPts, newEdges = e.joint.go(self, e)
-	    self.pts2d[index:index] = newPts                                         
-	    self.edges[index:index+1] = newEdges                                     
-	    for newEdge in newEdges:                                                 
-		newEdge.join(newEdge.length, self)                                   
-            e.remove(self)
-
     self.placeagain()
 
   def getTriangleDict(self):
@@ -345,7 +330,8 @@ class Face(object):
             name = self.name + ".d%d.e%d" % (i,j)
             pt1 = np.dot(self.transform2D, np.array(list(e[0][j-1]) + [0,1]))[0:2]
             pt2 = np.dot(self.transform2D, np.array(list(e[0][j]) + [0,1]))[0:2]
-            # XXX use EdgeType appropriately
+            # XXX use EdgeType appropriately 
+            # ??? deleted EdgeType
             edges.append([name, pt1, pt2, 1])
         else:
           name = self.name + ".d%d" % i
diff --git a/svggen/api/composables/graph/Graph.py b/svggen/api/composables/graph/Graph.py
index ffe397eac2300b11221a7594f64d22ebd0a43612..894028668db8744286a379240eca9728b4830bea 100644
--- a/svggen/api/composables/graph/Graph.py
+++ b/svggen/api/composables/graph/Graph.py
@@ -83,13 +83,13 @@ class Graph():
     self.rebuildEdges()
     return self
 
-  def attachFace(self, fromEdge, newFace, newEdge, prefix=None, angle=0, edgeType=None, joints=None):
+  def attachFace(self, fromEdge, newFace, newEdge, prefix=None, angle=0):
     # XXX should set angle from a face, not absolute angle of the face
     self.addFace(newFace, prefix)
 
     if fromEdge is not None:
       newEdge = prefixString(prefix, newEdge)
-      self.mergeEdge(fromEdge, newEdge, angle=angle, edgeType=edgeType, joints=joints)
+      self.mergeEdge(fromEdge, newEdge, angle=angle)
 
   def delFace(self, facename):
     for (i, f) in enumerate(self.faces):
@@ -140,7 +140,7 @@ class Graph():
   def addTab(self, edge1, edge2, angle=0, width=10):
     self.mergeEdge(edge1, edge2, angle=angle, tabWidth=width)
 
-  def mergeEdge(self, edge1, edge2, angle=0, tabWidth=None, edgeType=None, joints=None, swap=False):
+  def mergeEdge(self, edge1, edge2, angle=0, tabWidth=None, swap=False):
     e1 = self.getEdge(edge1)
     e2 = self.getEdge(edge2)
     if e1 is None:
@@ -161,11 +161,6 @@ class Graph():
       e2.mergeWith(e1, angle=angle, flip=True, tabWidth=tabWidth)
     self.edges.remove(e1)
     
-    e2.setType(edgeType)
-    if joints:
-        for joint in joints.joints:
-            e2.addJoint(joint)
-
     return self
 
   def splitEdge(self, edge):
@@ -186,13 +181,6 @@ class Graph():
     self.rebuildEdges()
     return new_edges_and_faces
 
-  def jointify(self, **kwargs):
-    for e in self.edges:
-        if e.isNotFlat() and "joint" in kwargs:
-            e.setType("JOINT")
-            e.addJoint(kwargs["joint"])
-            #print "jointing ", e.name
-
   def tabify(self, tabFace=None, tabDecoration=None, slotFace=None, slotDecoration=None, **kwargs):
     for e in self.edges:
       if e.isTab():
diff --git a/svggen/api/composables/graph/HyperEdge.py b/svggen/api/composables/graph/HyperEdge.py
index a6c09e85bc80917120ebab8ac569db89a92b4923..1d5e81fe7ad1e859f14c220f793fa29a5cd9ab73 100644
--- a/svggen/api/composables/graph/HyperEdge.py
+++ b/svggen/api/composables/graph/HyperEdge.py
@@ -3,9 +3,6 @@ from svggen.utils import mymath as np
 
 class HyperEdge:
 
-  #ANDYTODO: transform these into sublclasses of HyperEdge and/or componenet
-  edgeTypes = ["FOLD", "BEND", "JOINT"]
-
   @staticmethod
   def edge(allEdges, name, length, face, angle=0, flip=False):
     if allEdges is not None:
@@ -28,8 +25,6 @@ class HyperEdge:
     self.tabWidth = None
     self.pts2D = None
     self.pts3D = None
-    self.edgeType = "FOLD"
-    self.joint = None
 
     #self.pt1 = pt1
     #self.pt2 = pt2
@@ -50,15 +45,11 @@ class HyperEdge:
     self.name = name
 
   def isNotFlat(self):
-    return self.edgeType is "JOINT" or \
-        (self.edgeType is "FOLD" and any((x[0] for x in self.faces.values())))
+    return any((x[0] for x in self.faces.values()))
 
   def isTab(self):
     return self.tabWidth is not None
 
-  def isJoint(self):
-    return self.edgeType is "JOINT" and self.joint is not None
-
   def setAngle(self, face, angle, flip=False):
     if face in self.faces:
       self.faces[face] = (angle, flip)
@@ -145,20 +136,6 @@ class HyperEdge:
     self.pts2D = pts2D
     self.pts3D = pts3D
     
-  def setType(self, edgeType):
-    if edgeType is None:
-        return # do nothing
-    if edgeType not in self.edgeTypes:
-        raise Exception("Invalid edge type!")
-    self.edgeType = edgeType
-    
-  def addJoint(self, joint):
-    if not self.edgeType is "JOINT":
-        raise Exception("Trying to add joints to a non-joint edge")
-    # if not isinstance(joint, Joint.Joint):
-        # raise Exception("Not a joint!")
-    self.joint = joint
-
   def __eq__(self, other):
     return self.name == other.name
 
diff --git a/svggen/api/composables/graph/Joint.py b/svggen/api/composables/graph/Joint.py
deleted file mode 100644
index 3c410a1659f4ddda8c7886520ad8fedd6b786c70..0000000000000000000000000000000000000000
--- a/svggen/api/composables/graph/Joint.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from svggen.api.composables.graph.HyperEdge import HyperEdge
-import svggen.utils.mymath as np
-
-class Joint:
-    def __init__(self, **kwargs):
-        self.kwargs = kwargs
-    def go(face, edge):
-        pass
-
-class FingerJoint(Joint):
-    def go(self, face, edge):
-        inset = False
-        edgename = face.name + edge.name
-        index = face.edgeIndex(edge.name)                                       
-        angle, flip = edge.faces[face]
-
-        thickness = self.kwargs["thickness"]
-
-        coords = face.edgeCoords(index)
-        length = face.edgeLength(index) 
-        if inset:
-            length -= thickness
-
-        pt1 = np.array(coords[0])
-        pt2 = np.array(coords[1])
-
-        n = int(max(3, round(length * 1.0 / thickness))) # number of fingers
-        dt = length * 1.0 / n                # actual thickness of fingers
-        dlp = thickness / 2. 
-        dln = thickness / 2. # Only works for 90deg angles; np.sqrt(2) max
-        dl = dlp + dln # actual length of fingers
-
-        flip = flip and (n % 2 == 1)
-
-        dpt = (pt2 - pt1) * 1.0 * dt / face.edgeLength(index)
-        ppt = np.array((dpt[1], -dpt[0])) / dt
-
-        newEdges = []
-        newPts = []
-        newPt = coords[0]
-
-        def addNew(newEdge, newPt):
-            newEdges.append(newEdge)
-            newPts.append(newPt)
-            newEdge.join(newEdge.length, face)
-
-        if inset:
-        # inset from the edge for 3 face corners
-            newPt = newPt - ppt * dln
-            newEdge = HyperEdge(edgename + "fjx1", dln)
-            addNew(newEdge, newPt)
-
-            newPt = newPt + dpt * thickness / dt / 2.0
-            newEdge = HyperEdge(edgename + "fjx2", dt)
-            addNew(newEdge, newPt)
-
-            newPt = newPt + ppt * dln
-            newEdge = HyperEdge(edgename + "fjx3", dln)
-            addNew(newEdge, newPt)
-
-        if flip:
-            newPt = newPt + ppt * dlp
-            newEdge = HyperEdge(edgename + "fj0", dlp)
-        else:
-            newPt = newPt - ppt * dln
-            newEdge = HyperEdge(edgename + "fj0", dln)
-            
-
-        for i in range(int(n)):
-            addNew(newEdge, newPt)
-
-            newPt = newPt + dpt 
-            newEdge = HyperEdge(edgename + "fjd%d" % i, dt)
-            addNew(newEdge, newPt)
-
-            if flip:
-                newPt = newPt - ppt * dl
-            else:
-                newPt = newPt + ppt * dl
-            newEdge = HyperEdge(edgename + "fjp%d" % i, dl)
-            flip = not flip
-
-        if not flip:
-            addNew(newEdge, newPt)
-        else:
-            newPt = newPt - ppt * dl
-
-        if inset:
-            newPt = newPt + dpt * thickness / dt / 2.0
-            newEdge = HyperEdge(edgename + "fjy", dt)
-            addNew(newEdge, newPt)
-
-        newEdge = HyperEdge(edgename + "fjn", dln)
-        newEdges.append(newEdge)
-
-        return newPts, newEdges