Salome HOME
Copyrights update 2015.
[modules/geom.git] / src / GEOMImpl / GEOMImpl_ChamferDriver.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include <GEOMImpl_ChamferDriver.hxx>
24 #include <GEOMImpl_IChamfer.hxx>
25 #include <GEOMImpl_Types.hxx>
26 #include <GEOMImpl_ILocalOperations.hxx>
27 #include <GEOMImpl_Block6Explorer.hxx>
28 #include <GEOMUtils.hxx>
29 #include <GEOM_Function.hxx>
30
31 #include <BRepLib.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepTools.hxx>
34 #include <BRepFilletAPI_MakeChamfer.hxx>
35
36 #include <TopAbs.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Face.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Iterator.hxx>
42 #include <TopExp_Explorer.hxx>
43 #include <TopTools_MapOfShape.hxx>
44 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
45
46 #include <StdFail_NotDone.hxx>
47
48 //=======================================================================
49 //function : GetID
50 //purpose  :
51 //=======================================================================
52 const Standard_GUID& GEOMImpl_ChamferDriver::GetID()
53 {
54   static Standard_GUID aChamferDriver("FF1BBB42-5D14-4df2-980B-3A668264EA16");
55   return aChamferDriver;
56 }
57
58 //=======================================================================
59 //function : GEOMImpl_ChamferDriver
60 //purpose  :
61 //=======================================================================
62 GEOMImpl_ChamferDriver::GEOMImpl_ChamferDriver()
63 {
64 }
65
66 //=======================================================================
67 //function : isGoodForChamfer
68 //purpose  :
69 //=======================================================================
70 static Standard_Boolean isGoodForChamfer (const TopoDS_Shape& theShape)
71 {
72   if (theShape.ShapeType() == TopAbs_SHELL ||
73       theShape.ShapeType() == TopAbs_SOLID ||
74       theShape.ShapeType() == TopAbs_COMPSOLID) {
75     return Standard_True;
76   }
77
78   if (theShape.ShapeType() == TopAbs_COMPOUND) {
79     TopTools_MapOfShape mapShape;
80     TopoDS_Iterator It (theShape, Standard_False, Standard_False);
81     for (; It.More(); It.Next()) {
82       if (mapShape.Add(It.Value())) {
83         if (!isGoodForChamfer(It.Value())) {
84           return Standard_False;
85         }
86       }
87     }
88     return Standard_True;
89   }
90
91   return Standard_False;
92 }
93
94 //=======================================================================
95 //function : Execute
96 //purpose  :
97 //=======================================================================
98 Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const
99 {
100   if (Label().IsNull()) return 0;
101   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
102
103   GEOMImpl_IChamfer aCI (aFunction);
104   Standard_Integer aType = aFunction->GetType();
105
106   TopoDS_Shape aShape;
107
108   Handle(GEOM_Function) aRefShape = aCI.GetShape();
109   TopoDS_Shape aShapeBase = aRefShape->GetValue();
110
111   // Check the shape type. It have to be shell
112   // or solid, or compsolid, or compound of these shapes.
113   if (!isGoodForChamfer(aShapeBase)) {
114     StdFail_NotDone::Raise
115       ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes");
116   }
117
118   BRepFilletAPI_MakeChamfer fill (aShapeBase);
119
120   if (aType == CHAMFER_SHAPE_ALL) {
121     // symmetric chamfer on all edges
122     double aD = aCI.GetD();
123     TopTools_IndexedDataMapOfShapeListOfShape M;
124     GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
125     for (int i = 1; i <= M.Extent(); i++) {
126       TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
127       TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
128       if (!BRepTools::IsReallyClosed(E, F) &&
129           !BRep_Tool::Degenerated(E) &&
130           M.FindFromIndex(i).Extent() == 2)
131         fill.Add(aD, E, F);
132     }
133   }
134   else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) {
135     // chamfer on edges, common to two faces, with D1 on the first face
136
137     TopoDS_Shape aFace1, aFace2;
138     if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) &&
139         GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2))
140     {
141       TopoDS_Face F = TopoDS::Face(aFace1);
142
143       // fill map of edges of the second face
144       TopTools_MapOfShape aMap;
145       TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE);
146       for (; Exp2.More(); Exp2.Next()) {
147         aMap.Add(Exp2.Current());
148       }
149
150       // find edges of the first face, common with the second face
151       TopExp_Explorer Exp (aFace1, TopAbs_EDGE);
152       for (; Exp.More(); Exp.Next()) {
153         if (aMap.Contains(Exp.Current())) {
154           TopoDS_Edge E = TopoDS::Edge(Exp.Current());
155           if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
156           {
157             if ( aType == CHAMFER_SHAPE_EDGE )
158             {
159               double aD1 = aCI.GetD1();
160               double aD2 = aCI.GetD2();
161               fill.Add(aD1, aD2, E, F);
162             }
163             else
164             {
165               double aD = aCI.GetD();
166               double anAngle = aCI.GetAngle();
167               if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
168                 fill.AddDA(aD, anAngle, E, F);
169             }
170           }
171         }
172       }
173     }
174   }
175   else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) {
176     // chamfer on all edges of the selected faces, with D1 on the selected face
177     // (on first selected face, if the edge belongs to two selected faces)
178
179     int aLen = aCI.GetLength();
180     int ind = 1;
181     TopTools_MapOfShape aMap;
182     TopTools_IndexedDataMapOfShapeListOfShape M;
183     GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
184     for (; ind <= aLen; ind++)
185     {
186       TopoDS_Shape aShapeFace;
187       if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace))
188       {
189         TopoDS_Face F = TopoDS::Face(aShapeFace);
190         TopExp_Explorer Exp (F, TopAbs_EDGE);
191         for (; Exp.More(); Exp.Next()) {
192           if (!aMap.Contains(Exp.Current()))
193           {
194             TopoDS_Edge E = TopoDS::Edge(Exp.Current());
195             if (!BRepTools::IsReallyClosed(E, F) &&
196                 !BRep_Tool::Degenerated(E) &&
197                 M.FindFromKey(E).Extent() == 2)
198             {
199               if (aType == CHAMFER_SHAPE_FACES)
200               {
201                 double aD1 = aCI.GetD1();
202                 double aD2 = aCI.GetD2();
203                 fill.Add(aD1, aD2, E, F);
204               }
205               else
206               {
207                 double aD = aCI.GetD();
208                 double anAngle = aCI.GetAngle();
209                 if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
210                   fill.AddDA(aD, anAngle, E, F);
211               }
212             }
213           }
214         }
215       }
216     }
217   }
218   else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD)
219   {
220     // chamfer on selected edges with lenght param D1 & D2.
221
222     int aLen = aCI.GetLength();
223     int ind = 1;
224     TopTools_MapOfShape aMap;
225     TopTools_IndexedDataMapOfShapeListOfShape M;
226     GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
227     for (; ind <= aLen; ind++)
228     {
229       TopoDS_Shape aShapeEdge;
230       if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge))
231       {
232         TopoDS_Edge E = TopoDS::Edge(aShapeEdge);
233         const TopTools_ListOfShape& aFacesList = M.FindFromKey(E);
234         TopoDS_Face F = TopoDS::Face( aFacesList.First() );
235         if (aType == CHAMFER_SHAPE_EDGES)
236         {
237           double aD1 = aCI.GetD1();
238           double aD2 = aCI.GetD2();
239           fill.Add(aD1, aD2, E, F);
240         }
241         else
242         {
243           double aD = aCI.GetD();
244           double anAngle = aCI.GetAngle();
245           if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
246             fill.AddDA(aD, anAngle, E, F);
247         }
248       }
249     }
250   }
251   else {
252   }
253
254   fill.Build();
255   if (!fill.IsDone()) {
256     StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
257   }
258   aShape = fill.Shape();
259
260   if (aShape.IsNull()) return 0;
261
262   // reduce tolerances
263   GEOMUtils::FixShapeTolerance( aShape );
264
265   // fix SameParameter flag
266   BRepLib::SameParameter(aShape, 1.E-5, Standard_True);
267
268   aFunction->SetValue(aShape);
269
270   log.SetTouched(Label());
271
272   return 1;
273 }
274
275 //================================================================================
276 /*!
277  * \brief Returns a name of creation operation and names and values of creation parameters
278  */
279 //================================================================================
280
281 bool GEOMImpl_ChamferDriver::
282 GetCreationInformation(std::string&             theOperationName,
283                        std::vector<GEOM_Param>& theParams)
284 {
285   if (Label().IsNull()) return 0;
286   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
287
288   GEOMImpl_IChamfer aCI( function );
289   Standard_Integer aType = function->GetType();
290
291   theOperationName = "CHAMFER";
292
293   switch ( aType ) {
294   case CHAMFER_SHAPE_ALL:
295     AddParam( theParams, "Main Object", aCI.GetShape() );
296     AddParam( theParams, "Selected Edges", "all" );
297     AddParam( theParams, "D", aCI.GetD() );
298     break;
299   case CHAMFER_SHAPE_EDGE:
300     AddParam( theParams, "Main Object", aCI.GetShape() );
301     AddParam( theParams, "Face 1", aCI.GetFace1() );
302     AddParam( theParams, "Face 2", aCI.GetFace2() );
303     AddParam( theParams, "D1", aCI.GetD1() );
304     AddParam( theParams, "D2", aCI.GetD2() );
305     break;
306   case CHAMFER_SHAPE_EDGE_AD:
307     AddParam( theParams, "Main Object", aCI.GetShape() );
308     AddParam( theParams, "Face 1", aCI.GetFace1() );
309     AddParam( theParams, "Face 2", aCI.GetFace2() );
310     AddParam( theParams, "D", aCI.GetD() );
311     AddParam( theParams, "Angle", aCI.GetAngle() );
312     break;
313   case CHAMFER_SHAPE_FACES:
314     AddParam( theParams, "Main Object", aCI.GetShape() );
315     AddParam( theParams, "Selected Faces" );
316     if ( aCI.GetLength() > 1 )
317       theParams[1] << aCI.GetLength() << " faces: ";
318     for ( int i = 1, nb = aCI.GetLength(); i <= nb; ++i )
319       theParams[1] << aCI.GetFace(i) << " ";
320     AddParam( theParams, "D1", aCI.GetD1() );
321     AddParam( theParams, "D2", aCI.GetD2() );
322     break;
323   case CHAMFER_SHAPE_FACES_AD:
324     AddParam( theParams, "Main Object", aCI.GetShape() );
325     AddParam( theParams, "Selected Faces" );
326     if ( aCI.GetLength() > 1 )
327       theParams[1] << aCI.GetLength() << " faces: ";
328     for ( int i = 1, nb = aCI.GetLength(); i <= nb; ++i )
329       theParams[1] << aCI.GetFace(i) << " ";
330     AddParam( theParams, "D", aCI.GetD() );
331     AddParam( theParams, "Angle", aCI.GetAngle() );
332     break;
333   case CHAMFER_SHAPE_EDGES:
334     AddParam( theParams, "Main Object", aCI.GetShape() );
335     AddParam( theParams, "Selected Edges" );
336     if ( aCI.GetLength() > 1 )
337       theParams[1] << aCI.GetLength() << " edges: ";
338     for ( int i = 1, nb = aCI.GetLength(); i <= nb; ++i )
339       theParams[1] << aCI.GetEdge(i) << " ";
340     AddParam( theParams, "D1", aCI.GetD1() );
341     AddParam( theParams, "D2", aCI.GetD2() );
342     break;
343   case CHAMFER_SHAPE_EDGES_AD:
344     AddParam( theParams, "Main Object", aCI.GetShape() );
345     AddParam( theParams, "Selected Edges" );
346     if ( aCI.GetLength() > 1 )
347       theParams[1] << aCI.GetLength() << " edges: ";
348     for ( int i = 1, nb = aCI.GetLength(); i <= nb; ++i )
349       theParams[1] << aCI.GetFace(i) << " ";
350     AddParam( theParams, "D", aCI.GetD() );
351     AddParam( theParams, "Angle", aCI.GetAngle() );
352     break;
353   default:
354     return false;
355   }
356
357   return true;
358 }
359
360 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_ChamferDriver,GEOM_BaseDriver);
361
362 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ChamferDriver,GEOM_BaseDriver);