1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: GeomAlgoAPI_ShapeTools.h
4 // Created: 3 August 2015
5 // Author: Dmitry Bobylev
7 #include <GeomAlgoAPI_ShapeTools.h>
9 #include <GeomAlgoAPI_CompoundBuilder.h>
13 #include <BOPTools.hxx>
14 #include <BRepBuilderAPI_MakeFace.hxx>
15 #include <BRepGProp.hxx>
16 #include <BRepTools.hxx>
17 #include <BRep_Tool.hxx>
18 #include <Geom_Plane.hxx>
19 #include <GProp_GProps.hxx>
20 #include <NCollection_Vector.hxx>
21 #include <TCollection_AsciiString.hxx>
22 #include <TopoDS_Builder.hxx>
23 #include <TopoDS_Face.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Shell.hxx>
27 #include <TopExp_Explorer.hxx>
30 //=================================================================================================
31 double GeomAlgoAPI_ShapeTools::volume(std::shared_ptr<GeomAPI_Shape> theShape)
37 const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
41 BRepGProp::VolumeProperties(aShape, aGProps);
42 return aGProps.Mass();
45 //=================================================================================================
46 std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeTools::centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape)
50 return std::shared_ptr<GeomAPI_Pnt>();
52 const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
54 return std::shared_ptr<GeomAPI_Pnt>();
56 BRepGProp::SurfaceProperties(aShape, aGProps);
57 gp_Pnt aCentre = aGProps.CentreOfMass();
58 return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z()));
61 //=================================================================================================
62 void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
63 const GeomAPI_Shape::ShapeType theType,
64 ListOfShape& theCombinedShapes,
65 ListOfShape& theFreeShapes)
67 if(!theCompound.get()) {
71 if(theType != GeomAPI_Shape::SHELL && theType != GeomAPI_Shape::COMPSOLID) {
75 TopAbs_ShapeEnum aTS = TopAbs_EDGE;
76 TopAbs_ShapeEnum aTA = TopAbs_FACE;
77 if(theType == GeomAPI_Shape::COMPSOLID) {
82 // Map subshapes and shapes.
83 const TopoDS_Shape& aShapesComp = theCompound->impl<TopoDS_Shape>();
84 BOPCol_IndexedDataMapOfShapeListOfShape aMapEF;
85 BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapEF);
86 if(aMapEF.IsEmpty()) {
90 // Get all shapes with common subshapes and free shapes.
91 NCollection_Map<TopoDS_Shape> aFreeShapes;
92 NCollection_Vector<NCollection_Map<TopoDS_Shape>> aShapesWithCommonSubshapes;
93 for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) {
94 const TopoDS_Shape& aShape = anIter.Key();
95 BOPCol_ListOfShape& aListOfShape = anIter.ChangeValue();
96 if(aListOfShape.IsEmpty()) {
99 else if(aListOfShape.Size() == 1) {
100 const TopoDS_Shape& aF = aListOfShape.First();
102 aListOfShape.Clear();
104 NCollection_List<TopoDS_Shape> aTempList;
105 NCollection_Map<TopoDS_Shape> aTempMap;
106 const TopoDS_Shape& aF = aListOfShape.First();
107 const TopoDS_Shape& aL = aListOfShape.Last();
108 aTempList.Append(aF);
109 aTempList.Append(aL);
112 aFreeShapes.Remove(aF);
113 aFreeShapes.Remove(aL);
114 aListOfShape.Clear();
115 for(NCollection_List<TopoDS_Shape>::Iterator aTempIter(aTempList); aTempIter.More(); aTempIter.Next()) {
116 const TopoDS_Shape& aTempShape = aTempIter.Value();
117 for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) {
118 BOPCol_ListOfShape& aTempListOfShape = anIter.ChangeValue();
119 if(aTempListOfShape.IsEmpty()) {
121 } else if(aTempListOfShape.Size() == 1 && aTempListOfShape.First() == aTempShape) {
122 aTempListOfShape.Clear();
123 } else if(aTempListOfShape.Size() > 1) {
124 if(aTempListOfShape.First() == aTempShape) {
125 const TopoDS_Shape& aTL = aTempListOfShape.Last();
126 if(aTempMap.Add(aTL)) {
127 aTempList.Append(aTL);
128 aFreeShapes.Remove(aTL);
130 aTempListOfShape.Clear();
131 } else if(aTempListOfShape.Last() == aTempShape) {
132 const TopoDS_Shape& aTF = aTempListOfShape.First();
133 if(aTempMap.Add(aTF)) {
134 aTempList.Append(aTF);
135 aFreeShapes.Remove(aTF);
137 aTempListOfShape.Clear();
142 aShapesWithCommonSubshapes.Append(aTempMap);
146 // Combine shapes with common subshapes.
147 for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator anIter(aShapesWithCommonSubshapes); anIter.More(); anIter.Next()) {
149 TopoDS_CompSolid aCSolid;
150 TopoDS_Builder aBuilder;
151 theType == GeomAPI_Shape::COMPSOLID ? aBuilder.MakeCompSolid(aCSolid) : aBuilder.MakeShell(aShell);
152 NCollection_Map<TopoDS_Shape>& aShapesMap = anIter.ChangeValue();
153 for(TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) {
154 const TopoDS_Shape& aShape = anExp.Current();
155 if(aShapesMap.Contains(aShape)) {
156 theType == GeomAPI_Shape::COMPSOLID ? aBuilder.Add(aCSolid, aShape) : aBuilder.Add(aShell, aShape);
157 aShapesMap.Remove(aShape);
160 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
161 TopoDS_Shape* aSh = theType == GeomAPI_Shape::COMPSOLID ? new TopoDS_Shape(aCSolid) : new TopoDS_Shape(aShell);
162 aGeomShape->setImpl<TopoDS_Shape>(aSh);
163 theCombinedShapes.push_back(aGeomShape);
166 // Adding free shapes.
167 for(TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) {
168 const TopoDS_Shape& aShape = anExp.Current();
169 if(aFreeShapes.Contains(aShape)) {
170 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
171 aGeomShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
172 theFreeShapes.push_back(aGeomShape);
177 //=================================================================================================
178 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::faceToInfinitePlane(const std::shared_ptr<GeomAPI_Shape>& theFace)
181 return std::shared_ptr<GeomAPI_Shape>();
183 TopoDS_Face aPlaneFace = TopoDS::Face(theFace->impl<TopoDS_Shape>());
184 if (aPlaneFace.IsNull())
185 return std::shared_ptr<GeomAPI_Shape>();
187 Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aPlaneFace));
189 return std::shared_ptr<GeomAPI_Shape>();
191 // make an infinity face on the plane
192 TopoDS_Shape anInfiniteFace = BRepBuilderAPI_MakeFace(aPlane->Pln()).Shape();
194 std::shared_ptr<GeomAPI_Shape> aResult(new GeomAPI_Shape);
195 aResult->setImpl(new TopoDS_Shape(anInfiniteFace));