diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py
index 88e71f994ef..7e44ffeda8e 100644
--- a/scripts/startup/bl_ui/space_view3d.py
+++ b/scripts/startup/bl_ui/space_view3d.py
@@ -7625,7 +7625,10 @@ class VIEW3D_PT_transform_orientations(Panel):
             row = layout.row(align=False)
             row.prop(orientation, "name", text="", icon='OBJECT_ORIGIN')
             row.operator("transform.delete_orientation", text="", icon='X', emboss=False)
-
+            row = layout.row()
+            row.label(text="Origin:")
+            row = layout.row()
+            row.prop(orientation, "origin", text="", icon='OBJECT_ORIGIN')
 
 class VIEW3D_PT_gpencil_origin(Panel):
     bl_space_type = 'VIEW_3D'
diff --git a/source/blender/editors/transform/transform_orientations.cc b/source/blender/editors/transform/transform_orientations.cc
index 46e24fbd488..e46ceb84f0a 100644
--- a/source/blender/editors/transform/transform_orientations.cc
+++ b/source/blender/editors/transform/transform_orientations.cc
@@ -97,6 +97,7 @@ static TransformOrientation *createViewSpace(bContext *C,
 {
   RegionView3D *rv3d = CTX_wm_region_view3d(C);
   float mat[3][3];
+  float origin[3] = {0};
 
   if (!rv3d) {
     return nullptr;
@@ -116,7 +117,7 @@ static TransformOrientation *createViewSpace(bContext *C,
     }
   }
 
-  return addMatrixSpace(C, mat, name, overwrite);
+  return addMatrixSpace(C, mat, origin, name, overwrite);
 }
 
 static TransformOrientation *createObjectSpace(bContext *C,
@@ -127,6 +128,7 @@ static TransformOrientation *createObjectSpace(bContext *C,
   Base *base = CTX_data_active_base(C);
   Object *ob;
   float mat[3][3];
+  float origin[3];
 
   if (base == nullptr) {
     return nullptr;
@@ -135,6 +137,7 @@ static TransformOrientation *createObjectSpace(bContext *C,
   ob = base->object;
 
   copy_m3_m4(mat, ob->object_to_world);
+  copy_v3_v3(origin, ob->loc);
   normalize_m3(mat);
 
   /* use object name if no name is given */
@@ -142,7 +145,7 @@ static TransformOrientation *createObjectSpace(bContext *C,
     name = ob->id.name + 2;
   }
 
-  return addMatrixSpace(C, mat, name, overwrite);
+  return addMatrixSpace(C, mat, origin, name, overwrite);
 }
 
 static TransformOrientation *createBoneSpace(bContext *C,
@@ -152,8 +155,9 @@ static TransformOrientation *createBoneSpace(bContext *C,
 {
   float mat[3][3];
   float normal[3], plane[3];
+  float origin[3];
 
-  getTransformOrientation(C, normal, plane);
+  getTransformOrientation(C, normal, plane, origin);
 
   if (createSpaceNormalTangent(mat, normal, plane) == 0) {
     BKE_reports_prepend(reports, "Cannot use zero-length bone");
@@ -164,7 +168,7 @@ static TransformOrientation *createBoneSpace(bContext *C,
     name = "Bone";
   }
 
-  return addMatrixSpace(C, mat, name, overwrite);
+  return addMatrixSpace(C, mat, origin, name, overwrite);
 }
 
 static TransformOrientation *createCurveSpace(bContext *C,
@@ -174,8 +178,9 @@ static TransformOrientation *createCurveSpace(bContext *C,
 {
   float mat[3][3];
   float normal[3], plane[3];
+  float origin[3];
 
-  getTransformOrientation(C, normal, plane);
+  getTransformOrientation(C, normal, plane, origin);
 
   if (createSpaceNormalTangent(mat, normal, plane) == 0) {
     BKE_reports_prepend(reports, "Cannot use zero-length curve");
@@ -186,7 +191,7 @@ static TransformOrientation *createCurveSpace(bContext *C,
     name = "Curve";
   }
 
-  return addMatrixSpace(C, mat, name, overwrite);
+  return addMatrixSpace(C, mat, origin, name, overwrite);
 }
 
 static TransformOrientation *createMeshSpace(bContext *C,
@@ -197,8 +202,9 @@ static TransformOrientation *createMeshSpace(bContext *C,
   float mat[3][3];
   float normal[3], plane[3];
   int type;
+  float origin[3];
 
-  type = getTransformOrientation(C, normal, plane);
+  type = getTransformOrientation(C, normal, plane, origin);
 
   switch (type) {
     case ORIENTATION_VERT:
@@ -235,7 +241,7 @@ static TransformOrientation *createMeshSpace(bContext *C,
       return nullptr;
   }
 
-  return addMatrixSpace(C, mat, name, overwrite);
+  return addMatrixSpace(C, mat, origin, name, overwrite);
 }
 
 static bool test_rotmode_euler(short rotmode)
@@ -473,6 +479,7 @@ bool BIF_createTransformOrientation(bContext *C,
 
 TransformOrientation *addMatrixSpace(bContext *C,
                                      float mat[3][3],
+                                     float origin[3],
                                      const char *name,
                                      const bool overwrite)
 {
@@ -500,6 +507,7 @@ TransformOrientation *addMatrixSpace(bContext *C,
 
   /* copy matrix into transform space */
   copy_m3_m3(ts->mat, mat);
+  copy_v3_v3(ts->origin, origin);
 
   return ts;
 }
@@ -900,6 +908,7 @@ int getTransformOrientation_ex(const Scene *scene,
                                Object *obedit,
                                float normal[3],
                                float plane[3],
+                               float origin[3],
                                const short around)
 {
   int result = ORIENTATION_NONE;
@@ -907,6 +916,7 @@ int getTransformOrientation_ex(const Scene *scene,
 
   zero_v3(normal);
   zero_v3(plane);
+  zero_v3(origin);
 
   if (obedit) {
     float imat[3][3], mat[3][3];
@@ -1130,6 +1140,24 @@ int getTransformOrientation_ex(const Scene *scene,
         }
       }
 
+
+      if (em->bm->totvertsel > 1) {
+        BMIter iter;
+        BMVert *v;
+        int i = 0;
+
+        zero_v3(origin);
+
+        BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
+          if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+            add_v3_v3(origin, v->co);
+            i++;
+          }
+        }
+        mul_v3_fl(origin, 1.0f / i);
+        mul_m4_v3(ob->object_to_world, origin);
+      }
+
       /* not needed but this matches 2.68 and older behavior */
       negate_v3(plane);
 
@@ -1426,7 +1454,7 @@ int getTransformOrientation_ex(const Scene *scene,
   return result;
 }
 
-int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
+int getTransformOrientation(const bContext *C, float normal[3], float plane[3], float origin[3])
 {
   Object *obact = CTX_data_active_object(C);
   Object *obedit = CTX_data_edit_object(C);
@@ -1438,7 +1466,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3])
   ViewLayer *view_layer = CTX_data_view_layer(C);
   View3D *v3d = CTX_wm_view3d(C);
 
-  return getTransformOrientation_ex(scene, view_layer, v3d, obact, obedit, normal, plane, around);
+  return getTransformOrientation_ex(scene, view_layer, v3d, obact, obedit, normal, plane, origin, around);
 }
 
 void ED_getTransformOrientationMatrix(const Scene *scene,
@@ -1451,10 +1479,11 @@ void ED_getTransformOrientationMatrix(const Scene *scene,
 {
   float normal[3] = {0.0, 0.0, 0.0};
   float plane[3] = {0.0, 0.0, 0.0};
+  float origin[3] = {0.0, 0.0, 0.0};
 
   int type;
 
-  type = getTransformOrientation_ex(scene, view_layer, v3d, ob, obedit, normal, plane, around);
+  type = getTransformOrientation_ex(scene, view_layer, v3d, ob, obedit, normal, plane, origin, around);
 
   /* Fallback, when the plane can't be calculated. */
   if (ORIENTATION_USE_PLANE(type) && is_zero_v3(plane)) {
diff --git a/source/blender/editors/transform/transform_orientations.hh b/source/blender/editors/transform/transform_orientations.hh
index bfd38fff960..b65fcb2e8aa 100644
--- a/source/blender/editors/transform/transform_orientations.hh
+++ b/source/blender/editors/transform/transform_orientations.hh
@@ -47,6 +47,7 @@ bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const floa
 
 TransformOrientation *addMatrixSpace(bContext *C,
                                      float mat[3][3],
+                                     float origin[3],
                                      const char *name,
                                      bool overwrite);
 void applyTransformOrientation(const TransformOrientation *ts, float r_mat[3][3], char r_name[64]);
@@ -67,5 +68,6 @@ int getTransformOrientation_ex(const Scene *scene,
                                Object *obedit,
                                float normal[3],
                                float plane[3],
+                               float origin[3],
                                short around);
-int getTransformOrientation(const bContext *C, float normal[3], float plane[3]);
+int getTransformOrientation(const bContext *C, float normal[3], float plane[3], float origin [3]);
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index eac25b8e4ea..71c7886bfe1 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -294,7 +294,7 @@ typedef struct TransformOrientation {
   /** MAX_NAME. */
   char name[64];
   float mat[3][3];
-  char _pad[4];
+  float origin[3];
 } TransformOrientation;
 
 /** Some preview UI data need to be saved in file. */
diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc
index 89ef11b29bf..79f643651de 100644
--- a/source/blender/makesrna/intern/rna_scene.cc
+++ b/source/blender/makesrna/intern/rna_scene.cc
@@ -2900,6 +2900,12 @@ static void rna_def_transform_orientation(BlenderRNA *brna)
   RNA_def_struct_name_property(srna, prop);
   RNA_def_property_ui_text(prop, "Name", "Name of the custom transform orientation");
   RNA_def_property_update(prop, NC_SCENE | ND_TRANSFORM, nullptr);
+
+  prop = RNA_def_property(srna, "origin", PROP_FLOAT, PROP_XYZ);
+  RNA_def_property_array(prop, 3);
+  RNA_def_property_ui_text(prop, "Origin", "Origin of the custom transform orientation");
+  RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
 }
 
 static void rna_def_transform_orientation_slot(BlenderRNA *brna)
diff --git a/source/blender/tornavis/patches/MB_0017.h b/source/blender/tornavis/patches/MB_0017.h
new file mode 100644
index 00000000000..77c69577d55
--- /dev/null
+++ b/source/blender/tornavis/patches/MB_0017.h
@@ -0,0 +1 @@
+/* Empty file */
