+//==================================================================================================
+static void addSimpleShapeToList(const TopoDS_Shape& theShape, NCollection_List<TopoDS_Shape>& theList)
+{
+ if(theShape.IsNull()) {
+ return;
+ }
+
+ if(theShape.ShapeType() == TopAbs_COMPOUND) {
+ for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) {
+ addSimpleShapeToList(anIt.Value(), theList);
+ }
+ } else {
+ theList.Append(theShape);
+ }
+}
+
+//==================================================================================================
+static TopoDS_Compound makeCompound(const NCollection_List<TopoDS_Shape> theShapes)
+{
+ TopoDS_Compound aCompound;
+
+ BRep_Builder aBuilder;
+ aBuilder.MakeCompound(aCompound);
+
+ for(NCollection_List<TopoDS_Shape>::Iterator anIt(theShapes); anIt.More(); anIt.Next()) {
+ aBuilder.Add(aCompound, anIt.Value());
+ }
+
+ return aCompound;
+}
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::groupSharedTopology(const std::shared_ptr<GeomAPI_Shape> theCompound)
+{
+ GeomShapePtr aResult = theCompound;
+
+ if(!theCompound.get()) {
+ return aResult;
+ }
+
+ TopoDS_Shape anInShape = aResult->impl<TopoDS_Shape>();
+ NCollection_List<TopoDS_Shape> anUngroupedShapes;
+ addSimpleShapeToList(anInShape, anUngroupedShapes);
+
+ NCollection_Vector<NCollection_List<TopoDS_Shape>> aGroups;
+ while(!anUngroupedShapes.IsEmpty()) {
+ NCollection_List<TopoDS_Shape> aGroupedShapes;
+ aGroupedShapes.Append(anUngroupedShapes.First());
+ anUngroupedShapes.RemoveFirst();
+ for(NCollection_List<TopoDS_Shape>::Iterator aGroupIt(aGroupedShapes); aGroupIt.More(); aGroupIt.Next()) {
+ const TopoDS_Shape& aGroupShape = aGroupIt.Value();
+ for(NCollection_List<TopoDS_Shape>::Iterator anUngroupedIt(anUngroupedShapes); anUngroupedIt.More(); anUngroupedIt.Next()) {
+ const TopoDS_Shape& anUngroupedShape = anUngroupedIt.Value();
+ bool isFound = false;
+ for(TopExp_Explorer aGroupShapeExp(aGroupShape, TopAbs_VERTEX); aGroupShapeExp.More(); aGroupShapeExp.Next()) {
+ const TopoDS_Shape& aVertex1 = aGroupShapeExp.Current();
+ for(TopExp_Explorer anUngroupedShapeExp(anUngroupedShape, TopAbs_VERTEX); anUngroupedShapeExp.More(); anUngroupedShapeExp.Next()) {
+ const TopoDS_Shape& aVertex2 = anUngroupedShapeExp.Current();
+ if(aVertex1.IsSame(aVertex2)) {
+ aGroupedShapes.Append(anUngroupedShape);
+ anUngroupedShapes.Remove(anUngroupedIt);
+ isFound = true;
+ break;
+ }
+ }
+ if(isFound) {
+ break;
+ }
+ }
+ if(!anUngroupedIt.More()) {
+ break;
+ }
+ }
+ }
+ aGroups.Append(aGroupedShapes);
+ }
+
+ if(aGroups.Size() == 1) {
+ NCollection_List<TopoDS_Shape> aGroup = aGroups.First();
+ GeomShapePtr aGeomShape(new GeomAPI_Shape());
+ aGeomShape->setImpl(new TopoDS_Shape(makeCompound(aGroup)));
+ ListOfShape aCompSolids, aFreeSolids;
+ aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
+ GeomAPI_Shape::COMPSOLID,
+ aCompSolids,
+ aFreeSolids);
+ aResult = aGeomShape;
+ } else {
+ TopoDS_Compound aCompound;
+ BRep_Builder aBuilder;
+ aBuilder.MakeCompound(aCompound);
+ ListOfShape aCompSolids, aFreeSolids;
+ for(NCollection_Vector<NCollection_List<TopoDS_Shape>>::Iterator anIt(aGroups); anIt.More(); anIt.Next()) {
+ NCollection_List<TopoDS_Shape> aGroup = anIt.Value();
+ GeomShapePtr aGeomShape(new GeomAPI_Shape());
+ if(aGroup.Size() == 1) {
+ aGeomShape->setImpl(new TopoDS_Shape(aGroup.First()));
+ } else {
+ aGeomShape->setImpl(new TopoDS_Shape(makeCompound(aGroup)));
+ aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
+ GeomAPI_Shape::COMPSOLID,
+ aCompSolids,
+ aFreeSolids);
+ }
+ aBuilder.Add(aCompound, aGeomShape->impl<TopoDS_Shape>());
+ }
+
+ if(!aCompound.IsNull()) {
+ aResult->setImpl(new TopoDS_Shape(aCompound));
+ }
+ }
+
+ return aResult;
+}
+
+//==================================================================================================