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