Salome HOME
82e10914b4672236817955502ebe4f38b77e0b2d
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_GlueFaces.cpp
1 // Copyright (C) 2014-2023  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "GeomAlgoAPI_GlueFaces.h"
21
22 #include <GeomAPI_ShapeIterator.h>
23 #include <GEOMAlgo_Gluer2.hxx>
24 #include <BRep_Builder.hxx>
25 #include <BRepBuilderAPI_MakeShape.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <TopoDS_Iterator.hxx>
28 #include <TopoDS_Shape.hxx>
29
30 //==================================================================================================
31 GeomAlgoAPI_GlueFaces::GeomAlgoAPI_GlueFaces(const ListOfShape& theShapes, const double theTolerance/*=1.e-7*/, const bool theKeepNonSolids/*=true*/)
32 {
33   build(theShapes, theTolerance, theKeepNonSolids);
34 }
35
36 //==================================================================================================
37 void GeomAlgoAPI_GlueFaces::build(const ListOfShape& theShapes, const double theTolerance, const bool theKeepNonSolids)
38 {
39   if (theShapes.empty())
40   {
41     return;
42   }
43
44   // Create a compound of all shapes in the list
45   TopoDS_Shape aBaseShape;
46   if (theShapes.size() == 1)
47   {
48     aBaseShape = theShapes.front()->impl<TopoDS_Shape>();
49   }
50   else
51   {
52     TopoDS_Compound aCompound;
53     BRep_Builder aBuilder;
54     aBuilder.MakeCompound(aCompound);
55     ListOfShape::const_iterator anIt = theShapes.cbegin();
56     for (; anIt != theShapes.cend(); ++anIt)
57     {
58       const TopoDS_Shape& aShape = (*anIt)->impl<TopoDS_Shape>();
59       if (aShape.IsNull()) break;
60       aBuilder.Add(aCompound, aShape);
61     }
62     if (anIt == theShapes.cend())
63     {
64       aBaseShape = aCompound;
65     }
66     else
67     {
68       aBaseShape.Nullify();
69     }
70   }
71   if (aBaseShape.IsNull())
72   {
73     myError = "Shape for gluing is null";
74     return;
75   }
76
77   GEOMAlgo_Gluer2 aGlueAlgo;
78
79   // Initialization
80   aGlueAlgo.SetArgument(aBaseShape);
81   aGlueAlgo.SetTolerance(theTolerance);
82   Standard_Boolean aIsKeepNonSolids = theKeepNonSolids;
83   aGlueAlgo.SetKeepNonSolids(aIsKeepNonSolids);
84
85   // Detect interfered shapes
86   aGlueAlgo.Detect();
87   Standard_Integer iWrnDetect = aGlueAlgo.WarningStatus();
88   if (iWrnDetect == 2)
89   {
90     myError = "Glue Error Sticked Shapes";
91     return;
92   }
93
94   Standard_Integer iErr = aGlueAlgo.ErrorStatus();
95   if (iErr)
96   {
97     switch (iErr)
98     {
99     case 11:
100       myError = "GEOMAlgo_GlueDetector failed";
101       break;
102     case 13:
103     case 14:
104       myError = "PerformImagesToWork failed";
105       break;
106     default:
107       {
108         // description of all errors see in GEOMAlgo_Gluer2.cxx
109         myError = "Error in GEOMAlgo_Gluer2 with code ";
110         myError += std::to_string(iErr);
111         break;
112       }
113     }
114     return;
115   }
116
117   // Gluing
118   aGlueAlgo.Perform();
119   iErr = aGlueAlgo.ErrorStatus();
120   if (iErr)
121   {
122     switch (iErr)
123     {
124     case 11:
125       myError = "GEOMAlgo_GlueDetector failed";
126       break;
127     case 13:
128     case 14:
129       myError = "PerformImagesToWork failed";
130       break;
131     default:
132       {
133         // description of all errors see in GEOMAlgo_Gluer2.cxx
134         myError = "Error in GEOMAlgo_Gluer2 with code ";
135         myError += std::to_string(iErr);
136         break;
137       }
138     }
139     return;
140   }
141
142   Standard_Integer iWrn = aGlueAlgo.WarningStatus();
143   if (iWrn)
144   {
145     switch (iWrn)
146     {
147     case 1:
148       myError = "No shapes to glue";
149       break;
150     default:
151       // description of all warnings see in GEOMAlgo_Gluer2.cxx
152       myError = "Warning in GEOMAlgo_Gluer2 with code ";
153       myError += std::to_string(iWrn);
154       break;
155     }
156   }
157
158   // Result
159   TopoDS_Shape aResult = aGlueAlgo.Shape();
160
161   std::shared_ptr<GeomAPI_Shape> aResShape(new GeomAPI_Shape());
162   aResShape->setImpl(new TopoDS_Shape(aResult));
163   this->setShape(aResShape);
164   this->setDone(true);
165 }