0024830: Remove redundant keyword 'mutable' in CDL declarations
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_RemoveInternalWires.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <ShapeUpgrade_RemoveInternalWires.ixx>
15 #include <TopExp_Explorer.hxx>
16 #include <TopExp.hxx>
17 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
18 #include <TopTools_ListOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
20 #include <TopoDS_Face.hxx>
21 #include <TopoDS_Wire.hxx>  
22 #include <TopoDS_Iterator.hxx>
23 #include <TopoDS.hxx>
24 #include <ShapeAnalysis.hxx>
25 #include <ShapeExtend.hxx>
26 #include <TopTools_SequenceOfShape.hxx>
27 #include <ShapeExtend_WireData.hxx>
28 #include <ShapeBuild_ReShape.hxx>
29 #include <Precision.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
32
33 //=======================================================================
34 //function : ShapeUpgrade_RemoveInternalWires
35 //purpose  : 
36 //=======================================================================
37
38 ShapeUpgrade_RemoveInternalWires::ShapeUpgrade_RemoveInternalWires()
39 {
40   myMinArea =0.;
41   myRemoveFacesMode = Standard_True;
42   myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
43   Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
44   SetContext(aContext);
45   
46 }
47
48 //=======================================================================
49 //function : ShapeUpgrade_RemoveInternalWires
50 //purpose  : 
51 //=======================================================================
52
53 ShapeUpgrade_RemoveInternalWires::ShapeUpgrade_RemoveInternalWires(const TopoDS_Shape& theShape)
54 {
55   Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
56   SetContext(aContext);
57   Init(theShape);
58 }
59
60 //=======================================================================
61 //function : Init
62 //purpose  : 
63 //=======================================================================
64
65  void ShapeUpgrade_RemoveInternalWires::Init(const TopoDS_Shape& theShape) 
66 {
67   myShape = theShape;
68   Context()->Apply(theShape);
69   TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEdgeFaces);
70   myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
71   myMinArea =0.;
72   myRemoveFacesMode = Standard_True;
73 }
74
75 //=======================================================================
76 //function : Perform
77 //purpose  : 
78 //=======================================================================
79
80  Standard_Boolean ShapeUpgrade_RemoveInternalWires::Perform() 
81 {
82   Clear();
83   if(myShape.IsNull()) {
84     myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
85     return Standard_False;
86   }
87   TopExp_Explorer aExpF(myShape,TopAbs_FACE);
88   for( ; aExpF.More(); aExpF.Next()) {
89     TopoDS_Face aF = TopoDS::Face(aExpF.Current());
90     removeSmallWire(aF,TopoDS_Wire());
91   }
92   if(myRemoveFacesMode)
93     removeSmallFaces();
94   
95   myResult = Context()->Apply(myShape);
96   return Status( ShapeExtend_DONE );
97 }
98  
99 //=======================================================================
100 //function : Perform
101 //purpose  : 
102 //=======================================================================
103
104  Standard_Boolean ShapeUpgrade_RemoveInternalWires::Perform(const TopTools_SequenceOfShape& theSeqShapes) 
105 {
106   if(myShape.IsNull()) {
107     myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
108     return Standard_False;
109   }
110   Clear();
111   TopTools_IndexedDataMapOfShapeListOfShape aWireFaces;
112   Standard_Integer i =1, nb = theSeqShapes.Length();
113   for( ; i <= nb; i++) {
114     TopoDS_Shape aS = theSeqShapes.Value(i);
115     if(aS.ShapeType() == TopAbs_FACE)
116       removeSmallWire(aS,TopoDS_Wire());
117     else if(aS.ShapeType() == TopAbs_WIRE) {
118       if(!aWireFaces.Extent())
119         TopExp::MapShapesAndAncestors(myShape,TopAbs_WIRE,TopAbs_FACE,aWireFaces);
120       if(aWireFaces.Contains(aS)) {
121         const TopTools_ListOfShape& alfaces = aWireFaces.FindFromKey(aS);
122         TopTools_ListIteratorOfListOfShape liter(alfaces);
123         for( ; liter.More(); liter.Next())
124           removeSmallWire(liter.Value(),aS);
125       }
126         
127     }
128     
129   }
130   if(myRemoveFacesMode)
131       removeSmallFaces();
132   myResult = Context()->Apply(myShape);
133   return Status( ShapeExtend_DONE );
134 }
135
136 //=======================================================================
137 //function : removeSmallWire
138 //purpose  : 
139 //=======================================================================
140
141 void ShapeUpgrade_RemoveInternalWires::removeSmallWire (const TopoDS_Shape& theFace,
142                                                         const TopoDS_Shape& theWire) 
143 {
144   TopoDS_Face aF = TopoDS::Face(theFace);
145   TopoDS_Wire anOutW = ShapeAnalysis::OuterWire(aF);
146   TopoDS_Iterator aIt(aF);
147   for( ; aIt.More(); aIt.Next()) {
148     if(aIt.Value().ShapeType() != TopAbs_WIRE || aIt.Value().IsSame(anOutW))
149       continue;
150     //Handle(ShapeExtend_WireData) asewd = new  ShapeExtend_WireData();
151     TopoDS_Wire aW = TopoDS::Wire(aIt.Value());
152     if(!theWire.IsNull() && !theWire.IsSame(aW))
153       continue;
154     Standard_Real anArea = ShapeAnalysis::ContourArea(aW);
155     if(anArea < myMinArea -Precision::Confusion()) {
156       Context()->Remove(aW);
157       myRemoveWires.Append(aW);
158       myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1);
159       if(!myRemoveFacesMode )
160         continue;
161       
162       TopoDS_Iterator aIte(aW,Standard_False);
163       for( ; aIte.More(); aIte.Next()) {
164         TopoDS_Shape aE = aIte.Value();
165         if(myRemoveEdges.IsBound(aE))
166           myRemoveEdges.ChangeFind(aE).Append(aF);
167         else {
168           TopTools_ListOfShape alfaces;
169           alfaces.Append(aF);
170           myRemoveEdges.Bind(aE,alfaces);
171         }
172       }
173     }
174     
175   }
176 }
177
178 //=======================================================================
179 //function : removeSmallFaces
180 //purpose  : 
181 //=======================================================================
182
183 void ShapeUpgrade_RemoveInternalWires::removeSmallFaces ()
184 {
185   
186   Standard_Integer i =1;
187   for( ; i <= myRemoveWires.Length() ; i++) {
188     TopoDS_Shape aWire = myRemoveWires.Value(i);
189     TopoDS_Iterator aIte(aWire,Standard_False);
190     TopTools_IndexedMapOfShape aFaceCandidates;
191     //collecting all faces containing edges from removed wire
192     for( ; aIte.More(); aIte.Next()) {
193       
194       TopoDS_Shape aEdge =  aIte.Value();
195       if(!myEdgeFaces.Contains(aEdge)) {
196         myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
197         continue;
198       }
199       const TopTools_ListOfShape& aLface1 = myEdgeFaces.FindFromKey(aEdge);
200       const TopTools_ListOfShape& aLface2 = myRemoveEdges.Find(aEdge);
201       TopTools_ListIteratorOfListOfShape aliter(aLface1);
202       TopTools_ListIteratorOfListOfShape aliter2(aLface2);
203       for( ; aliter.More(); aliter.Next()) {
204         TopoDS_Shape aF = Context()->Apply(aliter.Value());
205         if(aF.IsNull())
206           continue;
207         Standard_Boolean isFind = Standard_False;
208         for( ; aliter2.More() && !isFind; aliter2.Next()) {
209           TopoDS_Shape aF2 = Context()->Apply(aliter2.Value());
210           isFind = aF.IsSame(aF2);
211         }
212         
213         if(!isFind) {
214           TopoDS_Wire aWout = ShapeAnalysis::OuterWire(TopoDS::Face(aF));
215           Standard_Boolean isOuter = Standard_False;
216           TopoDS_Iterator aIter(aWout,Standard_False);
217           for( ; aIter.More() && !isOuter; aIter.Next())
218             isOuter = aEdge.IsSame(aIter.Value());
219           if(isOuter)
220             aFaceCandidates.Add(aF);
221         }
222       }
223       
224     }
225     
226     //remove faces which have outer wire consist of only
227     //edges from removed wires and
228     //seam edges for faces based on conic surface or 
229     //in the case of a few faces based on the same conic surface
230     //the edges belogining these faces.
231     Standard_Integer k =1;
232     for( ; k <= aFaceCandidates.Extent(); k++) {
233       TopoDS_Shape aF = aFaceCandidates.FindKey(k);
234       TopoDS_Wire anOutW = ShapeAnalysis::OuterWire(TopoDS::Face(aF));
235       Handle(ShapeExtend_WireData) asewd = new ShapeExtend_WireData(anOutW);
236       Standard_Integer n =1, nbE = asewd->NbEdges();
237       Standard_Integer nbNotRemoved =0;
238       for( ; n <= nbE; n++) {
239         if(asewd->IsSeam(n))
240           continue;
241         TopoDS_Edge aE = asewd->Edge(n);
242         if(!myRemoveEdges.IsBound(aE) ) {
243           const TopTools_ListOfShape& aLface3 = myEdgeFaces.FindFromKey(aE);
244           TopTools_ListIteratorOfListOfShape aliter3(aLface3);
245           for( ; aliter3.More();aliter3.Next()) {
246             TopoDS_Shape aF2 = Context()->Apply(aliter3.Value());
247             if(aF2.IsNull())
248               continue;
249             if(!aF.IsSame(aF2) && !aFaceCandidates.Contains(aF2))
250               nbNotRemoved++;
251           }
252         }
253         
254       }
255     
256       if(!nbNotRemoved) {
257         Context()->Remove(aF);
258         myRemovedFaces.Append(aF);
259       }
260     }
261   }
262   
263   if(myRemovedFaces.Length())
264     myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
265 }
266
267 //=======================================================================
268 //function : Clear
269 //purpose  : 
270 //=======================================================================
271
272 void ShapeUpgrade_RemoveInternalWires::Clear()
273 {
274   myRemoveEdges.Clear();
275   myRemovedFaces.Clear();
276   myRemoveWires.Clear();
277   myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
278 }
279