Salome HOME
Partition namig fix
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Partition.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_Partition.cpp
4 // Created:     21 Aug 2015
5 // Author:      Sergey POKHODENKO
6
7 #include "GeomAlgoAPI_Partition.h"
8
9 #include <GeomAlgoAPI_DFLoader.h>
10 #include <GeomAlgoAPI_ShapeTools.h>
11
12 #include <GEOMAlgo_Splitter.hxx>
13
14 #include <Bnd_Box.hxx>
15 #include <BRep_Tool.hxx>
16 #include <BRepBndLib.hxx>
17 #include <BRepCheck_Analyzer.hxx>
18 #include <BRepLib_MakeFace.hxx>
19 #include <BRepTools.hxx>
20 #include <Geom_Plane.hxx>
21 #include <GeomLib_IsPlanarSurface.hxx>
22 #include <GeomLib_Tool.hxx>
23 #include <IntAna_IntConicQuad.hxx>
24 #include <IntAna_Quadric.hxx>
25 #include <Precision.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Builder.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopTools_ListOfShape.hxx>
31
32 //=================================================================================================
33 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Partition::make(const ListOfShape& theObjects,
34                                                            const ListOfShape& theTools)
35 {
36   GeomAlgoAPI_Partition aBoolAlgo(theObjects, theTools);
37   if(aBoolAlgo.isDone() && !aBoolAlgo.shape()->isNull() && aBoolAlgo.isValid()) {
38     return aBoolAlgo.shape();
39   }
40   return std::shared_ptr<GeomAPI_Shape>();
41 }
42
43 //=================================================================================================
44 GeomAlgoAPI_Partition::GeomAlgoAPI_Partition(const ListOfShape& theObjects,
45                                              const ListOfShape& theTools)
46 : myDone(false)
47 {
48   build(theObjects, theTools);
49 }
50
51
52 //=================================================================================================
53 void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
54                                   const ListOfShape& theTools)
55 {
56   if (theObjects.empty()) {
57     return;
58   }
59
60   // Creating partition operation.
61   GEOMAlgo_Splitter* anOperation = new GEOMAlgo_Splitter;
62   myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation, GeomAlgoAPI_MakeShape::BOPAlgoBuilder));
63
64   // Getting objects.
65   for (ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
66     const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
67     anOperation->AddArgument(aShape);
68   }
69
70   // Getting tools.
71   for (ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++) {
72     const TopoDS_Shape& aShape = (*aToolsIt)->impl<TopoDS_Shape>();
73     anOperation->AddTool(aShape);
74   }
75
76   // Building and getting result.
77   anOperation->Perform();
78   TopoDS_Shape aResult = anOperation->Shape();
79   myDone = !aResult.IsNull();
80   if (!myDone) {
81     return;
82   }
83
84   if(aResult.ShapeType() == TopAbs_COMPOUND) {
85     aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
86   }
87   if(aResult.ShapeType() == TopAbs_COMPOUND) {
88     std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
89     aCompound->setImpl(new TopoDS_Shape(aResult));
90     ListOfShape aCompSolids, aFreeSolids;
91     GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
92     if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
93       aResult = aCompSolids.front()->impl<TopoDS_Shape>();
94     } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
95       TopoDS_Compound aResultComp;
96       TopoDS_Builder aBuilder;
97       aBuilder.MakeCompound(aResultComp);
98       for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
99         aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
100       }
101       for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
102         aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
103       }
104       aResult = aResultComp;
105     }
106   }
107
108   // fill data map to keep correct orientation of sub-shapes
109   myMap.reset(new GeomAPI_DataMapOfShapeShape());
110   for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
111     std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
112     aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
113     myMap->bind(aCurrentShape, aCurrentShape);
114   }
115   myShape.reset(new GeomAPI_Shape());
116   myShape->setImpl(new TopoDS_Shape(aResult));
117 }
118
119 //=================================================================================================
120 const bool GeomAlgoAPI_Partition::isDone() const
121 {
122   return myDone;
123 }
124
125 //=================================================================================================
126 const bool GeomAlgoAPI_Partition::isValid() const
127 {
128   BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
129   return (aChecker.IsValid() == Standard_True);
130 }
131
132 //=================================================================================================
133 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Partition::shape() const
134 {
135   return myShape;
136 }
137
138 //=================================================================================================
139 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Partition::mapOfShapes() const
140 {
141   return myMap;
142 }
143
144 //=================================================================================================
145 std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Partition::makeShape() const
146 {
147   return myMkShape;
148 }