diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md
index 0cc82dc53c..7d716d0b63 100644
--- a/dox/dev_guides/upgrade/upgrade.md
+++ b/dox/dev_guides/upgrade/upgrade.md
@@ -1240,7 +1240,8 @@ The following Grid management methods within class V3d_Viewer do not implicitly
 * Types GeomPlate_Array1OfHCurveOnSurface and GeomPlate_HArray1OfHCurveOnSurface have been replaced with GeomPlate_Array1OfHCurve and GeomPlate_HArray1OfHCurve correspondingly (accept base class Adaptor3d_HCurve instead of Adaptor3d_HCurveOnSurface).
 * Enumeration *Image_PixMap::ImgFormat*, previously declared as nested enumeration within class *Image_PixMap*, has been moved to global namespace as *Image_Format* following OCCT coding rules.
   The enumeration values have suffix Image_Format_ and preserve previous name scheme for easy renaming of old values - e.g. Image_PixMap::ImgGray become Image_Format_Gray.
-  Old definitions are preserved as depreacated aliases to the new ones.
+  Old definitions are preserved as depreacated aliases to the new ones;
+* The method BOPAlgo_Builder::Origins() returns BOPCol_DataMapOfShapeListOfShape instead of BOPCol_DataMapOfShapeShape.
 
 @subsection upgrade_720_BOP_DataStructure BOP - Pairs of interfering indices
 
diff --git a/src/BOPAlgo/BOPAlgo_Builder.cxx b/src/BOPAlgo/BOPAlgo_Builder.cxx
index 598c5c905e..533fddcffb 100644
--- a/src/BOPAlgo/BOPAlgo_Builder.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder.cxx
@@ -148,7 +148,7 @@ const BOPCol_DataMapOfShapeListOfShape& BOPAlgo_Builder::Images()const
 //function : Origins
 //purpose  : 
 //=======================================================================
-const BOPCol_DataMapOfShapeShape& BOPAlgo_Builder::Origins()const
+const BOPCol_DataMapOfShapeListOfShape& BOPAlgo_Builder::Origins()const
 {
   return myOrigins;
 }
diff --git a/src/BOPAlgo/BOPAlgo_Builder.hxx b/src/BOPAlgo/BOPAlgo_Builder.hxx
index 0323b854a1..2938917fbb 100644
--- a/src/BOPAlgo/BOPAlgo_Builder.hxx
+++ b/src/BOPAlgo/BOPAlgo_Builder.hxx
@@ -86,7 +86,7 @@ Standard_EXPORT virtual ~BOPAlgo_Builder();
   Standard_EXPORT Standard_Boolean IsInterferred (const TopoDS_Shape& theS) const;
   
   //! Returns myOrigins.
-  Standard_EXPORT const BOPCol_DataMapOfShapeShape& Origins() const;
+  Standard_EXPORT const BOPCol_DataMapOfShapeListOfShape& Origins() const;
   
   //! Returns myShapesSD.
   Standard_EXPORT const BOPCol_DataMapOfShapeShape& ShapesSD() const;
@@ -171,7 +171,7 @@ protected:
   BOPCol_DataMapOfShapeListOfShape myImages;
   BOPCol_DataMapOfShapeShape myShapesSD;
   BOPCol_DataMapOfShapeListOfShape mySplits;
-  BOPCol_DataMapOfShapeShape myOrigins;
+  BOPCol_DataMapOfShapeListOfShape myOrigins;
   Standard_Boolean myNonDestructive;
   BOPAlgo_GlueEnum myGlue;
 
diff --git a/src/BOPAlgo/BOPAlgo_Builder_1.cxx b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
index 99ddca309f..7541264b1f 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_1.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
@@ -38,7 +38,7 @@
 //function : FillImagesVertices
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_Builder::FillImagesVertices()
+void BOPAlgo_Builder::FillImagesVertices()
 {
   myErrorStatus=0;
   //
@@ -59,6 +59,12 @@
     myImages.Bind(aV, aLVSD);
     //
     myShapesSD.Bind(aV, aVSD);
+    //
+    BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aVSD);
+    if (!pLOr) {
+      pLOr = myOrigins.Bound(aVSD, BOPCol_ListOfShape());
+    }
+    pLOr->Append(aV);
   }
 }
 //=======================================================================
@@ -97,7 +103,12 @@
       Standard_Integer nSpR = aPBR->Edge();
       const TopoDS_Shape& aSpR = myDS->Shape(nSpR);
       pLS->Append(aSpR);
-      myOrigins.Bind(aSpR, aE);
+      //
+      BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aSpR);
+      if (!pLOr) {
+        pLOr = myOrigins.Bound(aSpR, BOPCol_ListOfShape());
+      }
+      pLOr->Append(aE);
       //
       if (myDS->IsCommonBlockOnEdge(aPB)) {
         Standard_Integer nSp = aPB->Edge();
diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
index d6ff8f3082..cd79f0121f 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
@@ -707,7 +707,12 @@ void BOPAlgo_Builder::FillImagesFaces1()
     aItLS.Initialize(aLFIm);
     for (; aItLS.More(); aItLS.Next()) {
       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
-      myOrigins.Bind(aFSp, aF);
+      //
+      BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aFSp);
+      if (!pLOr) {
+        pLOr = myOrigins.Bound(aFSp, BOPCol_ListOfShape());
+      }
+      pLOr->Append(aF);
     }
     //
     // 3.
diff --git a/src/BOPAlgo/BOPAlgo_Builder_3.cxx b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
index 536afb91da..040de792fc 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_3.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
@@ -894,10 +894,7 @@ void BOPAlgo_Builder::BuildSplitSolids
     const BOPCol_ListOfShape& aLSR=aBS.Areas();
     //
     if (!myImages.IsBound(aS)) {
-      BOPCol_ListOfShape aLSx;
-      //
-      myImages.Bind(aS, aLSx);
-      BOPCol_ListOfShape& aLSIm=myImages.ChangeFind(aS);
+      BOPCol_ListOfShape* pLSx = myImages.Bound(aS, BOPCol_ListOfShape());
       //
       aIt.Initialize(aLSR);
       for (; aIt.More(); aIt.Next()) {
@@ -910,7 +907,13 @@ void BOPAlgo_Builder::BuildSplitSolids
         //
         const BOPTools_Set& aSTx=aMST.Added(aST);
         const TopoDS_Shape& aSx=aSTx.Shape();
-        aLSIm.Append(aSx);
+        pLSx->Append(aSx);
+        //
+        BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
+        if (!pLOr) {
+          pLOr = myOrigins.Bound(aSx, BOPCol_ListOfShape());
+        }
+        pLOr->Append(aS);
         //
         if (bFlagSD) {
           myShapesSD.Bind(aSR, aSx);
@@ -1105,8 +1108,8 @@ void BOPAlgo_Builder::FillInternalShapes()
         continue;
       }
       //
-      if(aMSOr.Contains(aSd)) {
-        //
+      if (aMSOr.Contains(aSd)) {
+        // make new solid
         TopoDS_Solid aSdx;
         //
         aBB.MakeSolid(aSdx);
@@ -1118,15 +1121,12 @@ void BOPAlgo_Builder::FillInternalShapes()
         //
         aBB.Add(aSdx, aSI);
         //
-        if (myImages.IsBound(aSdx)) {
-          BOPCol_ListOfShape& aLS=myImages.ChangeFind(aSdx);
-          aLS.Append(aSdx);
-        } 
-        else {
-          BOPCol_ListOfShape aLS;
-          aLS.Append(aSdx);
-          myImages.Bind(aSd, aLS);
-        }
+        // no need to check for images of aSd as aMSOr contains only original solids
+        BOPCol_ListOfShape* pLS = myImages.Bound(aSd, BOPCol_ListOfShape());
+        pLS->Append(aSdx);
+        //
+        BOPCol_ListOfShape* pLOr = myOrigins.Bound(aSdx, BOPCol_ListOfShape());
+        pLOr->Append(aSd);
         //
         aMSOr.Remove(aSd);
         aSd=aSdx;
diff --git a/src/BOPTest/BOPTest_DebugCommands.cxx b/src/BOPTest/BOPTest_DebugCommands.cxx
index 9e94ea4b45..28e91cca8c 100644
--- a/src/BOPTest/BOPTest_DebugCommands.cxx
+++ b/src/BOPTest/BOPTest_DebugCommands.cxx
@@ -1200,20 +1200,34 @@ Standard_Integer boporigin(Draw_Interpretor& di,
     return 0;
   }
   //
-  char buf[32];
-  //
   BOPAlgo_Builder& aBuilder = BOPTest_Objects::Builder();
-  const BOPCol_DataMapOfShapeShape& aDMI = aBuilder.Origins();
+  const BOPCol_DataMapOfShapeListOfShape& aDMI = aBuilder.Origins();
   if (!aDMI.IsBound(aS)) {
     di << " no origins found\n"; 
     return 0;
   }
   //
-  const TopoDS_Shape& aSx = aDMI.Find(aS);
-  //
+  char buf[32];
   sprintf(buf, "%s_or", a[1]);
-  DBRep::Set(buf, aSx);
   //
+  const BOPCol_ListOfShape& aLSx = aDMI.Find(aS);
+  if (aLSx.Extent() == 1) {
+    DBRep::Set(buf, aLSx.First());
+    di << "1 origin found\n" << buf << "\n";
+    return 0;
+  }
+  //
+  TopoDS_Compound aCOr;
+  BRep_Builder().MakeCompound(aCOr);
+  //
+  BOPCol_ListIteratorOfListOfShape aItLSx(aLSx);
+  for (; aItLSx.More(); aItLSx.Next()) {
+    BRep_Builder().Add(aCOr, aItLSx.Value());
+  }
+  //
+  DBRep::Set(buf, aCOr);
+  //
+  di << aLSx.Extent() << " origins found\n";
   di << buf << "\n";
   //
   return 0;
diff --git a/src/BRepFeat/BRepFeat_Builder.cxx b/src/BRepFeat/BRepFeat_Builder.cxx
index 36f766ce93..e1d3de5722 100644
--- a/src/BRepFeat/BRepFeat_Builder.cxx
+++ b/src/BRepFeat/BRepFeat_Builder.cxx
@@ -491,7 +491,12 @@
       aSx=aSTx.Shape();
       aSx.Orientation(anOriF);
       aLFIm.Append(aSx);
-      myOrigins.Bind(aSx, aF);
+      //
+      BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
+      if (!pLOr) {
+        pLOr = myOrigins.Bound(aSx, BOPCol_ListOfShape());
+      }
+      pLOr->Append(aF);
       //
       if (bFlagSD) {
         myShapesSD.Bind(aFR, aSx);
diff --git a/tests/bugs/modalg_6/bug28776 b/tests/bugs/modalg_6/bug28776
new file mode 100644
index 0000000000..606ccb8945
--- /dev/null
+++ b/tests/bugs/modalg_6/bug28776
@@ -0,0 +1,34 @@
+puts "========"
+puts "OCC28776"
+puts "========"
+puts ""
+####################################################################
+# Extend the field BOPAlgo_Builder::myOrigins so that the shape could have multiple origins
+####################################################################
+
+box b1 10 10 10
+box b2 10 10 10
+box b3 10 10 10
+
+bclearobjects
+bcleartools
+baddobjects b1 b2 b3
+bfillds
+bbuild r
+
+explode r v
+boporigin r_1
+checknbshapes r_1_or -vertex 3
+
+explode r e
+boporigin r_1
+checknbshapes r_1_or -edge 3
+
+explode r f
+boporigin r_1
+checknbshapes r_1_or -face 3
+
+explode r so
+boporigin r_1
+checknbshapes r_1_or -solid 3
+