Salome HOME
Fix of the bug when surfaces are not converted if to switch off Merge Surfaces flag
[plugins/canrecplugin.git] / src / CANRECPLUGINEngine / CANRECPluginImpl_Driver.cxx
1 // Copyright (C) 2014-2015  OPEN CASCADE
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 #include "CANRECPluginImpl_Driver.hxx"
20 #include "CANRECPluginImpl_Types.hxx"
21 #include "CANRECPluginImpl_ICanRec.hxx"
22
23 #include <GEOM_Function.hxx>
24
25 #include <BRep_Tool.hxx>
26 #include <BRepOffsetAPI_Sewing.hxx>
27 #include <Geom_Plane.hxx>
28 #include <Geom_Surface.hxx>
29 #include <Standard_Version.hxx>
30 #include <TopExp.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopoDS.hxx>
33 #include <TopoDS_Face.hxx>
34
35 #include <TFunction_Logbook.hxx>
36 #include <ShapeConvert_CanonicAPI.hxx>
37 #include <ShapeConvert_Surface.hxx>
38 #include <ShapeConvert_UnionFaces.hxx>
39 #include <ShapeConvert_UnionEdges.hxx>
40
41 #ifdef CANREC_HASLICENSE
42 #include "CANRECPluginImpl_license.h"
43 #include <OCCLicense_Activate.hxx>
44 #include <Standard_LicenseError.hxx>
45 #endif // CANREC_HASLICENSE
46
47 /**
48  * This function returns the number of shapes of a certain type.
49  *
50  * \param theShape the shape.
51  * \param theType the required type.
52  * \return the number of shapes of a certain type.
53  */
54 static Standard_Integer GetNbShapes(const TopoDS_Shape     &theShape,
55                                     const TopAbs_ShapeEnum  theType)
56 {
57   TopTools_IndexedMapOfShape aMapShapes;
58
59   TopExp::MapShapes(theShape, theType, aMapShapes);
60
61   const Standard_Integer aResult = aMapShapes.Extent();
62
63   return aResult;
64 }
65
66 const Standard_GUID& CANRECPluginImpl_Driver::GetID()
67 {
68   static Standard_GUID aGUID("7e1492bb-b4cd-4a40-ad8f-102902b0047e");
69   return aGUID;
70 }
71
72 Standard_Integer CANRECPluginImpl_Driver::GetNbCanonicalFaces
73                                   (const TopoDS_Shape &theShape)
74 {
75   TopExp_Explorer     anExp(theShape, TopAbs_FACE);
76   TopLoc_Location     aLoc;
77   Standard_Integer    aNbSurf = 0;
78   TopTools_MapOfShape aMapFence;
79
80   for (; anExp.More(); anExp.Next()) {
81     const TopoDS_Shape &aShFace = anExp.Current();
82
83     if (aMapFence.Add(aShFace)) {
84       TopoDS_Face          aFace    = TopoDS::Face(aShFace);
85       Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace, aLoc);
86
87       if(aSurface->IsKind(STANDARD_TYPE(Geom_Plane)) ||
88          ShapeConvert_Surface::IsCanonical(aSurface)) {
89         aNbSurf++;
90       }
91     }
92   }
93
94   return aNbSurf;
95 }
96
97 CANRECPluginImpl_Driver::CANRECPluginImpl_Driver()
98 {
99 }
100
101 CANRECPluginImpl_Driver::~CANRECPluginImpl_Driver()
102 {
103 }
104
105 Standard_Boolean CANRECPluginImpl_Driver::MustExecute( const TFunction_Logbook& ) const
106 {
107   return Standard_True;
108 }
109
110 void CANRECPluginImpl_Driver::Validate( TFunction_Logbook& ) const
111 {
112
113
114 Standard_Integer CANRECPluginImpl_Driver::Execute( TFunction_Logbook& log ) const
115 {
116   if ( Label().IsNull() ) return 0;
117   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction( Label() );
118
119   CANRECPluginImpl_ICanRec aData( aFunction );
120
121   // Getting data
122   bool isNeedMergeSurf = aData.GetNeedMergeSurf();
123   bool isNeedMergeCurves = aData.GetNeedMergeCurves();
124   double aTolerance = aData.GetTolerance();
125   Handle(GEOM_Function) anObject = aData.GetObject();
126   TopoDS_Shape aShape = anObject->GetValue();
127
128 #ifdef CANREC_HASLICENSE
129   try {
130     OCCLicense_Activate( "CANREC-"OCC_VERSION_STRING, CANREC_LICENSE );
131   }
132   catch (Standard_LicenseError) {
133     return 0;
134   }
135 #endif // CANREC_HASLICENSE
136
137   ShapeConvert_CanonicAPI aRecognizer;
138   aRecognizer.Tolerance() = aTolerance;
139
140   const Standard_Integer anInitNbFaces     = GetNbShapes(aShape, TopAbs_FACE);
141   const Standard_Integer anInitNbCanonical = GetNbCanonicalFaces(aShape);
142
143   // 1. Recognizing
144   aRecognizer.SetShape( aShape );
145   aRecognizer.UnifyMode() = false;
146   aRecognizer.Perform();
147   TopoDS_Shape aResultingShape = aRecognizer.Shape();
148     
149   // 2. Sewing
150   BRepOffsetAPI_Sewing aSewing( aTolerance );
151   aSewing.Add( aResultingShape );
152   aSewing.Perform();
153   aResultingShape = aSewing.SewedShape();
154
155   const Standard_Integer aNbConverted   =
156     GetNbCanonicalFaces(aResultingShape) - anInitNbCanonical;
157   Standard_Integer       aNbMergedFaces = -1;
158   Standard_Integer       aNbMergedEdges = -1;
159
160   // 3.1. Union Surfaces
161   if ( isNeedMergeSurf ) {
162     ShapeConvert_UnionFaces aFaceUnifier;
163     aFaceUnifier.GetTolerance() = aTolerance;
164     aResultingShape = aFaceUnifier.Perform( aResultingShape );
165     aNbMergedFaces  = anInitNbFaces - GetNbShapes(aResultingShape, TopAbs_FACE);
166   }
167   
168   // 3.2. Union Curves 
169   if ( isNeedMergeCurves ) {
170     ShapeConvert_UnionEdges anEdgeUnifier;
171     aNbMergedEdges   = GetNbShapes(aResultingShape, TopAbs_EDGE);
172     aResultingShape  = anEdgeUnifier.Perform( aResultingShape, aTolerance );
173     aNbMergedEdges  -= GetNbShapes(aResultingShape, TopAbs_EDGE);
174   }
175   
176   if ( aResultingShape.IsNull() ) return 0;
177
178   // Create statistics
179   Handle(TColStd_HArray1OfInteger) aStat = new TColStd_HArray1OfInteger(1, 5);
180
181   aStat->SetValue(1, anInitNbFaces);
182   aStat->SetValue(2, anInitNbCanonical);
183   aStat->SetValue(3, aNbConverted);
184   aStat->SetValue(4, aNbMergedFaces);
185   aStat->SetValue(5, aNbMergedEdges);
186
187   aData.SetStatistics(aStat);
188
189   aFunction->SetValue( aResultingShape );
190
191   log.SetTouched( Label() );
192   
193   return 1;
194 }
195
196 bool CANRECPluginImpl_Driver::
197 GetCreationInformation( std::string&             theOperationName,
198                         std::vector<GEOM_Param>& theParams )
199 {
200   if ( Label().IsNull() ) return 0;
201   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction( Label() );
202
203   CANRECPluginImpl_ICanRec aCI( aFunction );
204
205   theOperationName = "CANONICALRECOGNITION";
206   AddParam( theParams, PLUGIN_NAME, "CANRECPlugin" );
207   AddParam( theParams, "Tolerance", aCI.GetTolerance() );
208   AddParam( theParams, "Merge Surfaces", aCI.GetNeedMergeSurf() );
209   AddParam( theParams, "Merge Curves", aCI.GetNeedMergeCurves() );
210   
211   return true;
212 }
213
214 IMPLEMENT_STANDARD_HANDLE( CANRECPluginImpl_Driver, GEOM_BaseDriver );
215 IMPLEMENT_STANDARD_RTTIEXT( CANRECPluginImpl_Driver, GEOM_BaseDriver );