1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: GeomAlgoAPI_Partition.cpp
4 // Created: 21 Aug 2015
5 // Author: Sergey POKHODENKO
7 #include "GeomAlgoAPI_Partition.h"
9 #include <GeomAlgoAPI_DFLoader.h>
10 #include <GeomAlgoAPI_ShapeTools.h>
12 #include <GEOMAlgo_Splitter.hxx>
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>
28 #include <TopoDS_Builder.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopTools_ListOfShape.hxx>
32 //=================================================================================================
33 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Partition::make(const ListOfShape& theObjects,
34 const ListOfShape& theTools)
36 GeomAlgoAPI_Partition aBoolAlgo(theObjects, theTools);
37 if(aBoolAlgo.isDone() && !aBoolAlgo.shape()->isNull() && aBoolAlgo.isValid()) {
38 return aBoolAlgo.shape();
40 return std::shared_ptr<GeomAPI_Shape>();
43 //=================================================================================================
44 GeomAlgoAPI_Partition::GeomAlgoAPI_Partition(const ListOfShape& theObjects,
45 const ListOfShape& theTools)
48 build(theObjects, theTools);
52 //=================================================================================================
53 void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
54 const ListOfShape& theTools)
56 if (theObjects.empty()) {
60 // Creating partition operation.
61 GEOMAlgo_Splitter* anOperation = new GEOMAlgo_Splitter;
62 myMkShape.reset(new GeomAlgoAPI_MakeShape(anOperation, GeomAlgoAPI_MakeShape::BOPAlgoBuilder));
64 // Bounding box of all objects.
68 for (ListOfShape::const_iterator anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
69 const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
70 BRepBndLib::Add(aShape, aBndBox);
71 anOperation->AddArgument(aShape);
74 // We enlarge bounding box just to be sure that plane will be large enough to cut all objects.
76 Standard_Real aXArr[2] = {aBndBox.CornerMin().X(), aBndBox.CornerMax().X()};
77 Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()};
78 Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()};
81 for(int i = 0; i < 2; i++) {
82 for(int j = 0; j < 2; j++) {
83 for(int k = 0; k < 2; k++) {
84 aPoints[aNum] = gp_Pnt(aXArr[i], aYArr[j], aZArr[k]);
91 for (ListOfShape::const_iterator aToolsIt = theTools.begin(); aToolsIt != theTools.end(); aToolsIt++) {
92 TopoDS_Shape aShape = (*aToolsIt)->impl<TopoDS_Shape>();
93 if(aShape.ShapeType() == TopAbs_FACE) {
94 TopoDS_Face aFace = TopoDS::Face(aShape);
95 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
96 if (!aSurf.IsNull()) {
97 GeomLib_IsPlanarSurface isPlanar(aSurf);
98 if(isPlanar.IsPlanar()) {
99 Standard_Real UMin, UMax, VMin, VMax;
100 BRepTools::UVBounds(aFace, UMin, UMax, VMin, VMax);
101 if(UMin == -Precision::Infinite() && UMax == Precision::Infinite() &&
102 VMin == -Precision::Infinite() && VMax == Precision::Infinite()) {
103 const gp_Pln& aFacePln = isPlanar.Plan();
104 Handle(Geom_Plane) aFacePlane = new Geom_Plane(aFacePln);
105 IntAna_Quadric aQuadric(aFacePln);
106 UMin = UMax = VMin = VMax = 0;
107 for(int i = 0; i < 8; i++) {
108 gp_Lin aLin(aPoints[i], aFacePln.Axis().Direction());
109 IntAna_IntConicQuad anIntAna(aLin, aQuadric);
110 const gp_Pnt& aPntOnFace = anIntAna.Point(1);
111 Standard_Real aPntU(0), aPntV(0);
112 GeomLib_Tool::Parameters(aFacePlane, aPntOnFace, Precision::Confusion(), aPntU, aPntV);
113 if(aPntU < UMin) UMin = aPntU;
114 if(aPntU > UMax) UMax = aPntU;
115 if(aPntV < VMin) VMin = aPntV;
116 if(aPntV > VMax) VMax = aPntV;
118 aShape = BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face();
123 anOperation->AddTool(aShape);
126 // Building and getting result.
127 anOperation->Perform();
128 TopoDS_Shape aResult = anOperation->Shape();
129 myDone = !aResult.IsNull();
134 if(aResult.ShapeType() == TopAbs_COMPOUND) {
135 aResult = GeomAlgoAPI_DFLoader::refineResult(aResult);
137 if(aResult.ShapeType() == TopAbs_COMPOUND) {
138 std::shared_ptr<GeomAPI_Shape> aCompound(new GeomAPI_Shape);
139 aCompound->setImpl(new TopoDS_Shape(aResult));
140 ListOfShape aCompSolids, aFreeSolids;
141 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids);
142 if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) {
143 aResult = aCompSolids.front()->impl<TopoDS_Shape>();
144 } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) {
145 TopoDS_Compound aResultComp;
146 TopoDS_Builder aBuilder;
147 aBuilder.MakeCompound(aResultComp);
148 for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) {
149 aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
151 for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) {
152 aBuilder.Add(aResultComp, (*anIter)->impl<TopoDS_Shape>());
154 aResult = aResultComp;
158 // fill data map to keep correct orientation of sub-shapes
159 myMap.reset(new GeomAPI_DataMapOfShapeShape());
160 for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
161 std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
162 aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
163 myMap->bind(aCurrentShape, aCurrentShape);
165 myShape.reset(new GeomAPI_Shape());
166 myShape->setImpl(new TopoDS_Shape(aResult));
169 //=================================================================================================
170 const bool GeomAlgoAPI_Partition::isDone() const
175 //=================================================================================================
176 const bool GeomAlgoAPI_Partition::isValid() const
178 BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
179 return (aChecker.IsValid() == Standard_True);
182 //=================================================================================================
183 const std::shared_ptr<GeomAPI_Shape>& GeomAlgoAPI_Partition::shape() const
188 //=================================================================================================
189 std::shared_ptr<GeomAPI_DataMapOfShapeShape> GeomAlgoAPI_Partition::mapOfShapes() const
194 //=================================================================================================
195 std::shared_ptr<GeomAlgoAPI_MakeShape> GeomAlgoAPI_Partition::makeShape() const