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