0028828: Modeling Algorithms - New functionalities of BRepFilletAPI_MakeChamfer algorithm
[occt.git] / src / BRepTest / BRepTest_ChamferCommands.cxx
1 // Created on: 1995-09-25
2 // Created by: Stagiaire Flore Lautheanne
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Draw_Interpretor.hxx>
18 #include <BRepTest.hxx>
19 #include <Draw.hxx>
20 #include <DBRep.hxx>
21 #include <BRepFilletAPI_MakeChamfer.hxx>
22 #include <TopAbs_ShapeEnum.hxx>
23 #include <TopoDS.hxx>
24 #include <TopoDS_Face.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Shape.hxx>
28
29 #include <Precision.hxx>
30
31 //===============================================================================
32 // function : chamf_throat_with_penetration
33 // purpose  : command to construct chamfers with constant throat with penetration
34 //            on several edges
35 //            Here the chamfer is propagated on tangential edges to the 
36 //            required edge
37 //===============================================================================
38  
39 static Standard_Integer chamf_throat_with_penetration(Draw_Interpretor& di,
40                                                       Standard_Integer narg, 
41                                                       const char** a)
42 {
43   if (narg < 7)
44     return 1;
45
46   TopoDS_Shape S = DBRep::Get(a[2]);
47   if (S.IsNull()) return 1;
48   
49   TopoDS_Edge E;
50   TopoDS_Face F;
51   Standard_Real offset, throat;
52   Standard_Integer i      = 3;
53   Standard_Integer NbArg  = 4;
54   
55   BRepFilletAPI_MakeChamfer aMCh(S);
56   aMCh.SetMode(ChFiDS_ConstThroatWithPenetrationChamfer);
57   
58   while (i + NbArg <= narg) {
59     TopoDS_Shape aLocalEdge(DBRep::Get(a[i], TopAbs_EDGE));
60     E = TopoDS::Edge(aLocalEdge);
61     TopoDS_Shape aLocalFace(DBRep::Get(a[i + 1], TopAbs_FACE));
62     F = TopoDS::Face(aLocalFace);
63     //      E = TopoDS::Edge(DBRep::Get(a[i], TopAbs_EDGE));
64     //      F = TopoDS::Face(DBRep::Get(a[i + 1], TopAbs_FACE));
65     if (!E.IsNull() && !F.IsNull() && (aMCh.Contour(E) == 0) )  {
66       offset = Draw::Atof(a[i + 2]);
67       throat = Draw::Atof(a[i + 3]);
68       
69       if (offset > Precision::Confusion() &&
70           throat > offset)
71         aMCh.Add(offset,throat,E ,F);
72     }
73     i += NbArg;
74   }
75   
76   // compute the chamfer and display the result
77   if (aMCh.NbContours() == 0 )
78   {
79     //cout<<"No suitable edges to chamfer"<<endl;
80     di<<"No suitable edges to chamfer\n";
81     return 1;
82   }
83   else aMCh.Build();
84   
85   if (aMCh.IsDone()){
86     DBRep::Set(a[1],aMCh);
87     return 0;
88   }
89   else {
90     //cout<<"compute of chamfer failed"<<endl;
91     di<<"compute of chamfer failed\n";
92     return 1;
93   }
94 }
95
96 //===============================================================================
97 // function : chamf_throat
98 // purpose  : command to construct chamfers with constant throat on several edges
99 //            Here the chamfer is propagated on tangential edges to the 
100 //            required edge
101 //===============================================================================
102  
103 static Standard_Integer chamf_throat(Draw_Interpretor& di,
104                                      Standard_Integer narg, 
105                                      const char** a)
106 {
107   if (narg < 5)
108     return 1;
109
110   TopoDS_Shape S = DBRep::Get(a[2]);
111   if (S.IsNull()) return 1;
112   
113   TopoDS_Edge E;
114   Standard_Real throat;
115   Standard_Integer i      = 3;
116   
117   BRepFilletAPI_MakeChamfer aMCh(S);
118   aMCh.SetMode(ChFiDS_ConstThroatChamfer);
119   
120   while (i + 1 < narg) {
121     TopoDS_Shape aLocalEdge(DBRep::Get(a[i], TopAbs_EDGE));
122     E = TopoDS::Edge(aLocalEdge);
123     if (!E.IsNull() && (aMCh.Contour(E) == 0) )  {
124       throat = Draw::Atof(a[i + 1]);
125       
126       if (throat > Precision::Confusion()) 
127         aMCh.Add(throat, E);
128     }
129     i += 2;
130   }
131   
132   // compute the chamfer and display the result
133   if (aMCh.NbContours() == 0 )
134   {
135     //cout<<"No suitable edges to chamfer"<<endl;
136     di<<"No suitable edges to chamfer\n";
137     return 1;
138   }
139   else aMCh.Build();
140   
141   if (aMCh.IsDone()){
142     DBRep::Set(a[1],aMCh);
143     return 0;
144   }
145   else {
146     //cout<<"compute of chamfer failed"<<endl;
147     di<<"compute of chamfer failed\n";
148     return 1;
149   }
150 }
151
152 //=========================================================================
153 // function : chamfer
154 // purpose  : command to construct chamfers on several edges
155 //            Here the chamfer is propagated on tangential edges to the 
156 //            required edge
157 //=========================================================================
158  
159 static Standard_Integer chamfer(Draw_Interpretor& di,
160                                 Standard_Integer narg, 
161                                 const char** a)
162 {
163   // check the argument number of the command
164   if (narg == 1) {
165     di <<" help for chamf : \n";
166     di <<"   Construction by equal distances from edge          :  chamf newname shape edge dist\n";
167     di <<"   Construction by two distances from edge            :  chamf newname shape edge face dist1 dist2\n";
168     di <<"   Construction by distance from edge and given angle :  chamf newname shape edge face A dist angle\n";
169   }
170   else {
171     if (narg < 5)
172       return 1;
173   
174     TopoDS_Shape S = DBRep::Get(a[2]);
175     if (S.IsNull())
176       return 1;
177
178     TopoDS_Edge E;
179     TopoDS_Face F;
180     Standard_Real d1,d2, angle;
181     Standard_Integer i      = 3;
182
183     BRepFilletAPI_MakeChamfer aMCh(S);
184
185     while (i + 1 < narg) {
186       TopoDS_Shape aLocalEdge(DBRep::Get(a[i], TopAbs_EDGE));
187       if (aLocalEdge.IsNull())
188         return 1;
189       E = TopoDS::Edge(aLocalEdge);
190       TopoDS_Shape aLocalFace(DBRep::Get(a[i + 1], TopAbs_FACE));
191       if (aLocalFace.IsNull())
192       {
193         //symmetric chamfer (one distance)
194         d1 = atof(a[i + 1]);
195         if (aMCh.Contour(E) == 0 &&
196             d1 > Precision::Confusion())
197           aMCh.Add(d1, E);
198         i += 2;
199       }
200       else
201       {
202         F = TopoDS::Face(aLocalFace);
203
204         if (i + 3 < narg)
205         {
206           if (!strcasecmp(a[i + 2], "A") &&
207               i + 4 < narg)
208           {
209             //chamfer with distance and angle
210             d1    = Draw::Atof(a[i + 3]);
211             angle = Draw::Atof(a[i + 4]);
212             angle *= M_PI / 180.;
213             if (aMCh.Contour(E) == 0 &&
214                 d1    > Precision::Confusion() &&
215                 angle > Precision::Confusion() &&
216                 M_PI/2 - angle > Precision::Confusion())
217               aMCh.AddDA(d1, angle, E, F);
218             i += 5;
219           }
220           else
221           {
222             //chamfer with two distances
223             d1 = Draw::Atof(a[i + 2]);
224             d2 = Draw::Atof(a[i + 3]);
225             if (aMCh.Contour(E) == 0 &&
226                 d1 > Precision::Confusion() &&
227                 d2 > Precision::Confusion())
228               aMCh.Add(d1, d2, E, F);
229             i += 4;
230           }
231         }
232       }
233     }
234
235     // compute the chamfer and display the result
236     if (aMCh.NbContours() == 0 )
237       {
238         //cout<<"No suitable edges to chamfer"<<endl;
239         di<<"No suitable edges to chamfer\n";
240         return 1;
241       }
242     else aMCh.Build();
243
244     if (aMCh.IsDone()){
245       DBRep::Set(a[1],aMCh);
246       return 0;
247     }
248     else {
249       //cout<<"compute of chamfer failed"<<endl;
250       di<<"compute of chamfer failed\n";
251       return 1;
252     }
253   }
254   
255   return 0;
256 }
257
258
259
260 //=======================================================================
261 //function : ChamferCommands
262 //purpose  : 
263 //=======================================================================
264
265 void  BRepTest::ChamferCommands(Draw_Interpretor& theCommands)
266 {
267   static Standard_Boolean done = Standard_False;
268   if (done) return;
269   done = Standard_True;
270
271   DBRep::BasicCommands(theCommands);
272
273   const char* g = "TOPOLOGY Fillet construction commands";
274
275 //  theCommands.Add("chamf",
276 //                "chamf newname shape edge1 face1 dist1_1 dist1_2 edge2 face2 dist2_1 dist2_2 ... ",__FILE__,chamfer,g);
277
278   theCommands.Add("chamf",
279                   "for help call chamf without arguments",__FILE__,chamfer,g);
280
281   theCommands.Add("chamf_throat",
282                   "chamf_throat result shape edge throat"
283                   ,__FILE__,chamf_throat,g);
284   
285   theCommands.Add("chamf_throat_with_penetration",
286                   "chamf_throat_with_penetration result shape edge face offset throat",
287                   __FILE__,chamf_throat_with_penetration,g);
288 }