]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
Salome HOME
Combine solids in compounds after extrusion/revolution to compsolids
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_ShapeTools.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_ShapeTools.h
4 // Created:     3 August 2015
5 // Author:      Dmitry Bobylev
6
7 #include <GeomAlgoAPI_ShapeTools.h>
8
9 #include <GeomAlgoAPI_CompoundBuilder.h>
10
11 #include <BOPTools.hxx>
12 #include <BRepGProp.hxx>
13 #include <BRepTools.hxx>
14 #include <GProp_GProps.hxx>
15 #include <NCollection_Vector.hxx>
16 #include <TCollection_AsciiString.hxx>
17 #include <TopoDS_Builder.hxx>
18 #include <TopoDS_Shape.hxx>
19 #include <TopoDS_Shell.hxx>
20
21 //=================================================================================================
22 double GeomAlgoAPI_ShapeTools::volume(std::shared_ptr<GeomAPI_Shape> theShape)
23 {
24   GProp_GProps aGProps;
25   if(!theShape) {
26     return 0.0;
27   }
28   const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
29   if(aShape.IsNull()) {
30     return 0.0;
31   }
32   BRepGProp::VolumeProperties(aShape, aGProps);
33   return aGProps.Mass();
34 }
35
36 //=================================================================================================
37 std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_ShapeTools::centreOfMass(std::shared_ptr<GeomAPI_Shape> theShape)
38 {
39   GProp_GProps aGProps;
40   if(!theShape) {
41     return std::shared_ptr<GeomAPI_Pnt>();
42   }
43   const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
44   if(aShape.IsNull()) {
45     return std::shared_ptr<GeomAPI_Pnt>();
46   }
47   BRepGProp::SurfaceProperties(aShape, aGProps);
48   gp_Pnt aCentre = aGProps.CentreOfMass();
49   return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z()));
50 }
51
52 //=================================================================================================
53 void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr<GeomAPI_Shape> theCompound,
54                                            const GeomAPI_Shape::ShapeType theType,
55                                            ListOfShape& theCombinedShapes,
56                                            ListOfShape& theFreeShapes)
57 {
58   if(!theCompound.get()) {
59     return;
60   }
61
62   if(theType != GeomAPI_Shape::SHELL && theType != GeomAPI_Shape::COMPSOLID) {
63     return;
64   }
65
66   TopAbs_ShapeEnum aTS = TopAbs_EDGE;
67   TopAbs_ShapeEnum aTA = TopAbs_FACE;
68   if(theType == GeomAPI_Shape::COMPSOLID) {
69     aTS = TopAbs_FACE;
70     aTA = TopAbs_SOLID;
71   }
72
73   // Map subshapes and shapes.
74   const TopoDS_Shape& aShapesComp = theCompound->impl<TopoDS_Shape>();
75   BOPCol_IndexedDataMapOfShapeListOfShape aMapEF;
76   BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapEF);
77   if(aMapEF.IsEmpty()) {
78     return;
79   }
80
81   // Get all shapes with common subshapes and free shapes.
82   NCollection_Map<TopoDS_Shape> aFreeShapes;
83   NCollection_Vector<NCollection_Map<TopoDS_Shape>> aShapesWithCommonSubshapes;
84   for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) {
85     const TopoDS_Shape& aShape = anIter.Key();
86     BOPCol_ListOfShape& aListOfShape = anIter.ChangeValue();
87     if(aListOfShape.IsEmpty()) {
88       continue;
89     }
90     else if(aListOfShape.Size() == 1) {
91       aFreeShapes.Add(aListOfShape.First());
92       aListOfShape.Clear();
93     } else {
94       NCollection_Map<TopoDS_Shape> aTempMap;
95       aTempMap.Add(aListOfShape.First());
96       aTempMap.Add(aListOfShape.Last());
97       aFreeShapes.Remove(aListOfShape.First());
98       aFreeShapes.Remove(aListOfShape.Last());
99       aListOfShape.Clear();
100       for(NCollection_Map<TopoDS_Shape>::Iterator aTempIter(aTempMap); aTempIter.More(); aTempIter.Next()) {
101         const TopoDS_Shape& aTempShape = aTempIter.Value();
102         for(BOPCol_IndexedDataMapOfShapeListOfShape::Iterator anIter(aMapEF); anIter.More(); anIter.Next()) {
103           BOPCol_ListOfShape& aTempListOfShape = anIter.ChangeValue();
104           if(aTempListOfShape.IsEmpty()) {
105             continue;
106           } else if(aTempListOfShape.Size() == 1 && aTempListOfShape.First() == aTempShape) {
107             aTempListOfShape.Clear();
108           } else if(aTempListOfShape.Size() > 1) {
109             if(aTempListOfShape.First() == aTempShape) {
110               aTempMap.Add(aTempListOfShape.Last());
111               aFreeShapes.Remove(aTempListOfShape.Last());
112               aTempListOfShape.Clear();
113             } else if(aTempListOfShape.Last() == aTempShape) {
114               aTempMap.Add(aTempListOfShape.First());
115               aFreeShapes.Remove(aTempListOfShape.First());
116               aTempListOfShape.Clear();
117             }
118           }
119         }
120       }
121       aShapesWithCommonSubshapes.Append(aTempMap);
122     }
123   }
124
125   // Combine shapes with common subshapes.
126   for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator anIter(aShapesWithCommonSubshapes); anIter.More(); anIter.Next()) {
127     TopoDS_Shell aShell;
128     TopoDS_CompSolid aCSolid;
129     TopoDS_Builder aBuilder;
130     theType == GeomAPI_Shape::COMPSOLID ? aBuilder.MakeCompSolid(aCSolid) : aBuilder.MakeShell(aShell);
131     const NCollection_Map<TopoDS_Shape>& aShapesMap = anIter.Value();
132     for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aShapesMap); aShIter.More(); aShIter.Next()) {
133       const TopoDS_Shape& aShape = aShIter.Value();
134       theType == GeomAPI_Shape::COMPSOLID ? aBuilder.Add(aCSolid, aShape) : aBuilder.Add(aShell, aShape);
135     }
136     std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
137     TopoDS_Shape* aSh = theType == GeomAPI_Shape::COMPSOLID ? new TopoDS_Shape(aCSolid) : new TopoDS_Shape(aShell);
138     aGeomShape->setImpl<TopoDS_Shape>(aSh);
139     theCombinedShapes.push_back(aGeomShape);
140   }
141
142   // Adding free shapes.
143   for(NCollection_Map<TopoDS_Shape>::Iterator aShIter(aFreeShapes); aShIter.More(); aShIter.Next()) {
144     const TopoDS_Shape& aShape = aShIter.Value();
145     std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
146     aGeomShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
147     theFreeShapes.push_back(aGeomShape);
148   }
149 }