-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File: GeomAlgoAPI_ShapeTools.h
-// Created: 3 August 2015
-// Author: Dmitry Bobylev
+// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
#include "GeomAlgoAPI_ShapeTools.h"
NCollection_List<TopoDS_Shape> anUngroupedShapes, aStillUngroupedShapes;
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);
+ // Iterate over all shapes and find shapes with shared vertices.
+ TopTools_ListOfShape aMapOrder;
+ BOPCol_DataMapOfShapeListOfShape aVertexShapesMap;
+ for(NCollection_List<TopoDS_Shape>::Iterator aShapesIt(anUngroupedShapes);
+ aShapesIt.More();
+ aShapesIt.Next()) {
+ const TopoDS_Shape& aShape = aShapesIt.Value();
+ for(TopExp_Explorer aShapeExp(aShape, TopAbs_VERTEX);
+ aShapeExp.More();
+ aShapeExp.Next()) {
+ const TopoDS_Shape& aVertex = aShapeExp.Current();
+ if (!aVertexShapesMap.IsBound(aVertex)) {
+ NCollection_List<TopoDS_Shape> aList;
+ aList.Append(aShape);
+ aMapOrder.Append(aVertex);
+ aVertexShapesMap.Bind(aVertex, aList);
+ } else {
+ if(!aVertexShapesMap.ChangeFind(aVertex).Contains(aShape)) {
+ aVertexShapesMap.ChangeFind(aVertex).Append(aShape);
+ }
+ }
+ }
+ }
+
+ // Iterate over the map and group shapes.
+ NCollection_Vector<TopTools_ListOfShape> aGroups;
+ while (!aMapOrder.IsEmpty()) {
+ // Get first group of shapes in map, and then unbind it.
+ const TopoDS_Shape& aKey = aMapOrder.First();
+ TopTools_ListOfShape aGroupedShapes = aVertexShapesMap.Find(aKey);
+ aVertexShapesMap.UnBind(aKey);
+ aMapOrder.Remove(aKey);
+ // Iterate over shapes in this group and add to it shapes from groups in map.
+ for(TopTools_ListOfShape::Iterator aGroupIt(aGroupedShapes);
aGroupIt.More(); aGroupIt.Next()) {
const TopoDS_Shape& aGroupedShape = aGroupIt.Value();
- for(TopExp_Explorer aGroupShapeExp(aGroupedShape, TopAbs_VERTEX);
- aGroupShapeExp.More();
- aGroupShapeExp.Next()) {
- // Find all shapes which have same vertex.
- aStillUngroupedShapes.Clear();
- const TopoDS_Shape& aVertex1 = aGroupShapeExp.Current();
- for(NCollection_List<TopoDS_Shape>::Iterator anUngroupedIt(anUngroupedShapes);
- anUngroupedIt.More();
- anUngroupedIt.Next()) {
- const TopoDS_Shape& anUngroupedShape = anUngroupedIt.Value();
- bool isAdded = false;
- for(TopExp_Explorer anUgroupedShapeExp(anUngroupedShape, TopAbs_VERTEX);
- anUgroupedShapeExp.More();
- anUgroupedShapeExp.Next()) {
- const TopoDS_Shape& aVertex2 = anUgroupedShapeExp.Current();
- if(aVertex1.IsSame(aVertex2)) {
- aGroupedShapes.Append(anUngroupedShape);
- isAdded = true;
- break;
- }
- }
- if(!isAdded) {
- aStillUngroupedShapes.Append(anUngroupedShape);
- }
+ TopTools_ListOfShape aKeysToUnbind;
+ for(TopTools_ListOfShape::Iterator aKeysIt(aMapOrder);
+ aKeysIt.More();
+ aKeysIt.Next()) {
+ const TopTools_ListOfShape& aGroupInMap = aVertexShapesMap(aKeysIt.Value());
+ if(!aGroupInMap.Contains(aGroupedShape)) {
+ // Group in map does not containt shape from our group, so go to the next group in map.
+ continue;
}
- anUngroupedShapes = aStillUngroupedShapes;
- if(anUngroupedShapes.IsEmpty()) {
- break;
+ // Iterate over shape in group in map, and add new shapes into our group.
+ for(TopTools_ListOfShape::Iterator aGroupInMapIt(aGroupInMap);
+ aGroupInMapIt.More();
+ aGroupInMapIt.Next()) {
+ const TopoDS_Shape& aShape = aGroupInMapIt.Value();
+ if (!aGroupedShapes.Contains(aShape)) {
+ aGroupedShapes.Append(aShape);
+ }
}
+ // Save key to unbind from this map.
+ aKeysToUnbind.Append(aKeysIt.Value());
}
- if(anUngroupedShapes.IsEmpty()) {
- break;
+ // Unbind groups from map that we added to our group.
+ for(TopTools_ListOfShape::Iterator aKeysIt(aKeysToUnbind);
+ aKeysIt.More();
+ aKeysIt.Next()) {
+ aVertexShapesMap.UnBind(aKeysIt.Value());
+ aMapOrder.Remove(aKeysIt.Value());
+ }
+ }
+ // Sort shapes.
+ TopTools_ListOfShape aSortedGroup;
+ for(int aST = TopAbs_COMPOUND; aST <= TopAbs_SHAPE; ++aST) {
+ TopTools_ListOfShape::Iterator anIt(aGroupedShapes);
+ while (anIt.More()) {
+ if(anIt.Value().ShapeType() == aST) {
+ aSortedGroup.Append(anIt.Value());
+ aGroupedShapes.Remove(anIt);
+ } else {
+ anIt.Next();
+ }
}
}
- aGroups.Append(aGroupedShapes);
+ aGroups.Append(aSortedGroup);
}
TopoDS_Compound aCompound;
return true;
}
-//==================================================================================================
-bool GeomAlgoAPI_ShapeTools::isShapesIntersects(
- const std::shared_ptr<GeomAPI_Shape> theShape1,
- const std::shared_ptr<GeomAPI_Shape> theShape2)
-{
- if(!theShape1.get() || !theShape2.get()) {
- return false;
- }
-
- const TopoDS_Shape& aShape1 = theShape1->impl<TopoDS_Shape>();
- const TopoDS_Shape& aShape2 = theShape2->impl<TopoDS_Shape>();
-
- BRepExtrema_DistShapeShape aDist(aShape1, aShape2);
- aDist.Perform();
- if(aDist.IsDone() && aDist.Value() < Precision::Confusion()) {
- return true;
- }
-
- return false;
-}
-
//==================================================================================================
bool GeomAlgoAPI_ShapeTools::isShapeValid(const std::shared_ptr<GeomAPI_Shape> theShape)
{
const GeomAlgoAPI_ShapeTools::PointToRefsMap& thePointsInfo,
std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes)
{
- // General Fuse to split edge by vertices
+ // to split shape at least one point should be presented in the points container
+ if (thePointsInfo.empty())
+ return;
+
+ // General Fuse to split edge by vertices
BOPAlgo_Builder aBOP;
TopoDS_Edge aBaseEdge = theBaseShape->impl<TopoDS_Edge>();
// Rebuild closed edge to place vertex to one of split points.