Salome HOME
a6440f7bb075404ae8c3b704d3788dc0a7fb90f5
[modules/geom.git] / src / GEOMImpl / GEOMImpl_Fillet2dDriver.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, 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.
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 <Standard_Stream.hxx>
21
22 #include <GEOMImpl_Fillet2dDriver.hxx>
23 #include <GEOMImpl_IFillet2d.hxx>
24 #include <GEOMImpl_Types.hxx>
25 #include <GEOMImpl_ILocalOperations.hxx>
26 #include <GEOMImpl_Block6Explorer.hxx>
27 #include <GEOM_Function.hxx>
28
29 #include <BRepFilletAPI_MakeFillet2d.hxx>
30 #include <BRepCheck_Analyzer.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRep_Builder.hxx>
33
34 #include <TopoDS.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Iterator.hxx>
38 #include <TopAbs.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
41 #include <TopTools_ListIteratorOfListOfShape.hxx>
42
43 #include <ShapeFix_ShapeTolerance.hxx>
44 #include <ShapeFix_Shape.hxx>
45
46 #include <Precision.hxx>
47 #include <gp_Pnt.hxx>
48 #include <StdFail_NotDone.hxx>
49
50 //=======================================================================
51 //function : GetID
52 //purpose  :
53 //=======================================================================
54 const Standard_GUID& GEOMImpl_Fillet2dDriver::GetID()
55 {
56   static Standard_GUID aFillet2dDriver("FF1AAB41-2A14-4df2-581B-3A568163BA46");
57   return aFillet2dDriver;
58 }
59
60
61 //=======================================================================
62 //function : GEOMImpl_Fillet2dDriver
63 //purpose  :
64 //=======================================================================
65 GEOMImpl_Fillet2dDriver::GEOMImpl_Fillet2dDriver()
66 {
67 }
68
69 //=======================================================================
70 //function : Execute
71 //purpose  :
72 //=======================================================================
73 Standard_Integer GEOMImpl_Fillet2dDriver::Execute(TFunction_Logbook& log) const
74 {
75   if (Label().IsNull()) return 0;
76   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
77
78   GEOMImpl_IFillet2d aCI (aFunction);
79
80   TopoDS_Shape aShape;
81
82   Handle(GEOM_Function) aRefShape = aCI.GetShape();
83   TopoDS_Shape aFaceShape = aRefShape->GetValue();
84
85   int aLen = aCI.GetLength();
86   double rad = aCI.GetR();
87
88   if (aFaceShape.ShapeType() == TopAbs_FACE) {
89     BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(aFaceShape));
90
91     int ind = 1;
92     for (; ind <= aLen; ind++) {
93       TopoDS_Shape aShapeVertex;
94       if (GEOMImpl_ILocalOperations::GetSubShape
95           (aFaceShape, aCI.GetVertex(ind), aShapeVertex)) {
96         fillet2d.AddFillet(TopoDS::Vertex(aShapeVertex), rad);
97       }
98     }
99
100     fillet2d.Build();
101     if (!fillet2d.IsDone()) {
102       StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
103     }
104     aShape = fillet2d.Shape();
105   }
106   else if (aFaceShape.ShapeType() == TopAbs_SHELL) {
107     // 1. Map vertices to faces to build fillets only on corner vertices
108     TopTools_IndexedDataMapOfShapeListOfShape mapVertexFaces;
109     GEOMImpl_Block6Explorer::MapShapesAndAncestors
110       (aFaceShape, TopAbs_VERTEX, TopAbs_FACE, mapVertexFaces);
111
112     // 2. Map faces to vertices
113     TopTools_IndexedDataMapOfShapeListOfShape mapFaceVertices;
114     TopTools_ListOfShape empty;
115     int ind = 1;
116     for (; ind <= aLen; ind++) {
117       TopoDS_Shape aVi;
118       if (GEOMImpl_ILocalOperations::GetSubShape(aFaceShape, aCI.GetVertex(ind), aVi)) {
119         Standard_Integer aVi_index = mapVertexFaces.FindIndex(aVi);
120         if (aVi_index > 0) {
121           const TopTools_ListOfShape& aFacesOfVi = mapVertexFaces(aVi_index);
122           if (aFacesOfVi.Extent() == 1) { // we use only corner vertices of shell
123             TopoDS_Shape aFi = aFacesOfVi.First();
124             Standard_Integer aFi_index = mapFaceVertices.FindIndex(aFi);
125             if (aFi_index == 0) aFi_index = mapFaceVertices.Add(aFi, empty);
126             mapFaceVertices(aFi_index).Append(aVi);
127           }
128         }
129       }
130     }
131
132     // 3. Build fillet on each given vertex
133     TopoDS_Shell aResult;
134     BRep_Builder B;
135     B.MakeShell(aResult);
136
137     TopoDS_Iterator It (aFaceShape, Standard_True, Standard_True);
138     TopTools_MapOfShape mapShape;
139     for (; It.More(); It.Next()) {
140       if (mapShape.Add(It.Value())) {
141         Standard_Integer aFi_index = mapFaceVertices.FindIndex(It.Value());
142         if (aFi_index == 0) {
143           // No fillets requested on this face, add it as is
144           B.Add(aResult, It.Value());
145         }
146         else {
147           // Build a fillet and add the changed face
148           BRepFilletAPI_MakeFillet2d fillet2d (TopoDS::Face(It.Value()));
149           const TopTools_ListOfShape& aVertsOfFi = mapFaceVertices(aFi_index);
150           TopTools_ListIteratorOfListOfShape itV (aVertsOfFi);
151           for (; itV.More(); itV.Next()) {
152             fillet2d.AddFillet(TopoDS::Vertex(itV.Value()), rad);
153           }
154
155           fillet2d.Build();
156           if (!fillet2d.IsDone()) {
157             StdFail_NotDone::Raise("2D Fillet can't be computed on the given shape with the given radius");
158           }
159           TopoDS_Shape aFillet = fillet2d.Shape();
160
161           B.Add(aResult, aFillet);
162         }
163       }
164     }
165
166     // 4. Build a shell
167     // ?TODO?
168     aShape = aResult;
169   }
170   else {
171     Standard_ConstructionError::Raise("Wrong arguments: a face or a shell must be given");
172   }
173
174   if (aShape.IsNull()) return 0;
175
176   aFunction->SetValue(aShape);
177   log.SetTouched(Label());
178
179   return 1;
180 }
181
182 //================================================================================
183 /*!
184  * \brief Returns a name of creation operation and names and values of creation parameters
185  */
186 //================================================================================
187
188 bool GEOMImpl_Fillet2dDriver::
189 GetCreationInformation(std::string&             theOperationName,
190                        std::vector<GEOM_Param>& theParams)
191 {
192   if (Label().IsNull()) return 0;
193   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
194
195   GEOMImpl_IFillet2d aCI( function );
196   Standard_Integer aType = function->GetType();
197
198   theOperationName = "FILLET_2D";
199
200   switch ( aType ) {
201   case FILLET_2D_SHAPE_VERTEXES:
202     AddParam( theParams, "Face", aCI.GetShape() );
203     AddParam( theParams, "Vertexes");
204     if ( aCI.GetLength() > 1 )
205       theParams[1] << aCI.GetLength() << " vertexes: ";
206     for (int i = 1; i <= aCI.GetLength(); ++i )
207       theParams[1] << aCI.GetVertex( i ) << " ";
208     AddParam( theParams, "Radius", aCI.GetR() );
209     break;
210   default:
211     return false;
212   }
213   
214   return true;
215 }
216
217 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_Fillet2dDriver,GEOM_BaseDriver);
218 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_Fillet2dDriver,GEOM_BaseDriver);