0030480: Visualization - Clear of Select3D_SensitiveGroup does not update internal...
[occt.git] / src / BRepPrimAPI / BRepPrimAPI_MakeRevol.cxx
1 // Created on: 1993-10-14
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-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 // Modified by skv - Fri Mar  4 15:50:09 2005
18 // Add methods for supporting history.
19
20 #include <BRep_TEdge.hxx>
21 #include <BRepLib.hxx>
22 #include <BRepPrimAPI_MakeRevol.hxx>
23 #include <BRepSweep_Revol.hxx>
24 #include <gp_Ax1.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <TopTools_DataMapOfShapeListOfShape.hxx>
28 #include <BRepTools_ReShape.hxx>
29 // perform checks on the argument
30 static const TopoDS_Shape& check(const TopoDS_Shape& S)
31 {
32  BRepLib::BuildCurves3d(S);
33    return S;
34 }
35
36 //=======================================================================
37 //function : BRepPrimAPI_MakeRevol
38 //purpose  : 
39 //=======================================================================
40
41 BRepPrimAPI_MakeRevol::BRepPrimAPI_MakeRevol(const TopoDS_Shape& S, 
42                                      const gp_Ax1& A, 
43                                      const Standard_Real D, 
44                                      const Standard_Boolean Copy) :
45        myRevol(check(S),A,D,Copy)
46 {
47   Build();
48 }
49
50
51 //=======================================================================
52 //function : BRepPrimAPI_MakeRevol
53 //purpose  : 
54 //=======================================================================
55
56 BRepPrimAPI_MakeRevol::BRepPrimAPI_MakeRevol(const TopoDS_Shape& S, 
57                                      const gp_Ax1& A, 
58                                      const Standard_Boolean Copy) :
59        myRevol(check(S),A,Copy)
60 {
61   Build();
62 }
63
64
65 //=======================================================================
66 //function : Revol
67 //purpose  : 
68 //=======================================================================
69
70 const BRepSweep_Revol&  BRepPrimAPI_MakeRevol::Revol() const 
71 {
72   return myRevol;
73 }
74
75
76 //=======================================================================
77 //function : Build
78 //purpose  : 
79 //=======================================================================
80
81 void  BRepPrimAPI_MakeRevol::Build()
82 {
83   myShape = myRevol.Shape();
84   BRepLib::UpdateInnerTolerances(myShape);
85   
86   Done();
87   myHist.Nullify();
88   myDegenerated.Clear();
89   TopTools_DataMapOfShapeListOfShape aDegE;
90   BRep_Builder aBB;
91
92   TopExp_Explorer anExp(myShape, TopAbs_EDGE);
93   //Problem is that some degenerated edges can be shared by different faces.
94   //It is not valid for correct shape.
95   //To solve problem it is possible to copy shared degenerated edge for each face, which has it, and 
96   //replace shared edge by its copy
97   for (; anExp.More(); anExp.Next()) {
98     const TopoDS_Shape &anEdge = anExp.Current();
99     Handle(BRep_TEdge)  aTEdge = Handle(BRep_TEdge)::DownCast(anEdge.TShape());
100
101     if (aTEdge->Degenerated())
102     {
103       TopTools_ListOfShape* anL = aDegE.ChangeSeek(anEdge);
104       if (anL)
105       {
106         //Make the copy if degenerated edge occurs more then once
107         TopoDS_Shape aCopyE = anEdge.EmptyCopied();
108         aCopyE.Orientation(TopAbs_FORWARD);
109         TopoDS_Iterator aVIter(anEdge.Oriented(TopAbs_FORWARD), Standard_False);
110         for (; aVIter.More(); aVIter.Next())
111         {
112           aBB.Add(aCopyE, aVIter.Value());
113         }
114         aCopyE.Orientation(anEdge.Orientation());
115         anL->Append(aCopyE);
116         myDegenerated.Append(aCopyE);
117       }
118       else
119       {
120         anL = aDegE.Bound(anEdge, TopTools_ListOfShape());
121         anL->Append(anEdge);
122         myDegenerated.Append(anEdge);
123       }
124     }
125   }
126   if (!myDegenerated.IsEmpty())
127   {
128     BRepTools_ReShape aSubs;
129     TopTools_DataMapOfShapeListOfShape aDegF;
130     Standard_Boolean isReplaced = Standard_False;
131     anExp.Init(myShape, TopAbs_FACE);
132     //Replace degenerated edge by its copies for different faces
133     //First, for each face list of d.e. is created
134     for (; anExp.More(); anExp.Next())
135     {
136       const TopoDS_Shape& aF = anExp.Current();
137       TopExp_Explorer anExpE(aF, TopAbs_EDGE);
138       for (; anExpE.More(); anExpE.Next())
139       {
140         const TopoDS_Shape &anE = anExpE.Current();
141         if (BRep_Tool::Degenerated(TopoDS::Edge(anE)))
142         {
143           TopTools_ListOfShape* anL = aDegF.ChangeSeek(aF);
144           if (!anL)
145           {
146             anL = aDegF.Bound(aF, TopTools_ListOfShape());
147           }
148           anL->Append(anE);
149         }
150       }
151     }
152     //
153     //Second, replace edges by copies using ReShape
154     BRepTools_ReShape aSubsF;
155     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aFIter(aDegF);
156     for (; aFIter.More(); aFIter.Next())
157     {
158       aSubs.Clear();
159       isReplaced = Standard_False;
160       const TopoDS_Shape& aF = aFIter.Key();
161       const TopTools_ListOfShape& aDEL = aFIter.ChangeValue();
162       TopTools_ListIteratorOfListOfShape anEIter(aDEL);
163       for (; anEIter.More(); anEIter.Next())
164       {
165         const TopoDS_Shape& anE = anEIter.Value();
166         if (aDegE.IsBound(anE))
167         {
168           TopTools_ListOfShape& aCEL = aDegE.ChangeFind(anE);
169           TopTools_ListIteratorOfListOfShape anIt(aCEL);
170           for (; anIt.More(); anIt.Next())
171           {
172             if (anIt.Value().IsEqual(anE))
173             {
174               //First occurence of initial deg. edge is not replaced
175               aCEL.Remove(anIt);
176               break;
177             }
178             if (anIt.Value().Orientation() == anE.Orientation())
179             {
180               //All other occurences of anE are replaced by any copy
181               //with suitable orientation
182               isReplaced = Standard_True;
183               aSubs.Replace(anE, anIt.Value());
184               aCEL.Remove(anIt);
185               break;
186             }
187           }
188         }
189       }
190       if (isReplaced)
191       {
192         TopoDS_Shape aNF = aSubs.Apply(aF);
193         aSubsF.Replace(aF, aNF);
194         if (myHist.IsNull())
195         {
196           myHist = aSubs.History();
197         }
198         else
199         {
200           myHist->Merge(aSubs.History());
201         }
202         myShape = aSubsF.Apply(myShape);
203         myHist->Merge(aSubsF.History());
204         //Pair aF->aNF is in history after first replacing of edge by aNF = aSubs.Apply(aF)
205         //After merging history for replacing faces, modified list for aF contains two exemplar of aNF
206         //So, using ReplaceModified clears modified list for aF and leaves only one exemplar of aNF
207         myHist->ReplaceModified(aF, aNF);
208         aSubsF.Clear();
209       }
210     }
211   }
212 }
213
214
215 //=======================================================================
216 //function : FirstShape
217 //purpose  : 
218 //=======================================================================
219
220 TopoDS_Shape BRepPrimAPI_MakeRevol::FirstShape()
221 {
222   return myRevol.FirstShape();
223 }
224
225
226 //=======================================================================
227 //function : LastShape
228 //purpose  : 
229 //=======================================================================
230
231 TopoDS_Shape BRepPrimAPI_MakeRevol::LastShape()
232 {
233   return myRevol.LastShape();
234 }
235
236 //=======================================================================
237 //function : Generated
238 //purpose  : 
239 //=======================================================================
240 const TopTools_ListOfShape& BRepPrimAPI_MakeRevol::Generated (const TopoDS_Shape& S)
241 {
242   myGenerated.Clear();
243
244   if (!myRevol.IsUsed(S))
245   {
246     return myGenerated;
247   }
248
249   TopoDS_Shape aGS = myRevol.Shape(S);
250   if (!aGS.IsNull())
251   { 
252     if (BRepTools_History::IsSupportedType(aGS))
253     {
254       if (aGS.ShapeType() == TopAbs_EDGE)
255       {
256         Standard_Boolean isDeg = BRep_Tool::Degenerated(TopoDS::Edge(aGS));
257         if (isDeg)
258         {
259           TopTools_ListIteratorOfListOfShape anIt(myDegenerated);
260           for (; anIt.More(); anIt.Next())
261           {
262             if (aGS.IsSame(anIt.Value()))
263             {
264               myGenerated.Append(aGS);
265               if (!myHist.IsNull())
266               {
267                 TopTools_ListIteratorOfListOfShape anIt1(myHist->Modified(aGS));
268                 for (; anIt1.More(); anIt1.Next())
269                 {
270                   myGenerated.Append(anIt1.Value());
271                 }
272                 return myGenerated;
273               }
274             }
275           }
276           return myGenerated;
277         }
278       }
279       //
280       if (myHist.IsNull())
281       {
282         myGenerated.Append(aGS);
283         return myGenerated;
284       }
285       //
286       if (myHist->Modified(aGS).IsEmpty())
287       {
288         myGenerated.Append(aGS);
289         return myGenerated;
290       }
291       //
292       TopTools_ListIteratorOfListOfShape anIt(myHist->Modified(aGS));
293       for (; anIt.More(); anIt.Next())
294       {
295         myGenerated.Append(anIt.Value());
296       }
297     }
298   }
299   return myGenerated;
300 }
301 //=======================================================================
302 //function : IsDeleted
303 //purpose  : 
304 //=======================================================================
305 Standard_Boolean BRepPrimAPI_MakeRevol::IsDeleted(const TopoDS_Shape& S)
306 {
307   return !myRevol.IsUsed(S);
308 }
309
310
311 //=======================================================================
312 //function : FirstShape
313 //purpose  : This method returns the shape of the beginning of the revolution,
314 //           generated with theShape (subShape of the generating shape).
315 //=======================================================================
316
317 TopoDS_Shape BRepPrimAPI_MakeRevol::FirstShape(const TopoDS_Shape &theShape)
318 {
319   return myRevol.FirstShape(theShape);
320 }
321
322
323 //=======================================================================
324 //function : LastShape
325 //purpose  : This method returns the shape of the end of the revolution,
326 //           generated with theShape (subShape of the generating shape).
327 //=======================================================================
328
329 TopoDS_Shape BRepPrimAPI_MakeRevol::LastShape(const TopoDS_Shape &theShape)
330 {
331   return myRevol.LastShape(theShape);
332 }
333
334 //=======================================================================
335 //function : HasDegenerated
336 //purpose  : 
337 //=======================================================================
338
339 Standard_Boolean BRepPrimAPI_MakeRevol::HasDegenerated () const
340 {
341   return (!myDegenerated.IsEmpty());
342 }
343
344
345 //=======================================================================
346 //function : Degenerated
347 //purpose  : 
348 //=======================================================================
349
350 const TopTools_ListOfShape& BRepPrimAPI_MakeRevol::Degenerated () const
351 {
352   return myDegenerated;
353 }
354