b311480e |
1 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
2 | // |
3 | // The content of this file is subject to the Open CASCADE Technology Public |
4 | // License Version 6.5 (the "License"). You may not use the content of this file |
5 | // except in compliance with the License. Please obtain a copy of the License |
6 | // at http://www.opencascade.org and read it completely before using this file. |
7 | // |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
10 | // |
11 | // The Original Code and all software distributed under the License is |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
13 | // Initial Developer hereby disclaims all such warranties, including without |
14 | // limitation, any warranties of merchantability, fitness for a particular |
15 | // purpose or non-infringement. Please see the License for the specific terms |
16 | // and conditions governing the rights and limitations under the License. |
17 | |
7fd59977 |
18 | #include <ShapeUpgrade_RemoveInternalWires.ixx> |
19 | #include <TopExp_Explorer.hxx> |
20 | #include <TopExp.hxx> |
21 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
22 | #include <TopTools_ListOfShape.hxx> |
23 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
24 | #include <TopoDS_Face.hxx> |
25 | #include <TopoDS_Wire.hxx> |
26 | #include <TopoDS_Iterator.hxx> |
27 | #include <TopoDS.hxx> |
28 | #include <ShapeAnalysis.hxx> |
29 | #include <ShapeExtend.hxx> |
30 | #include <TopTools_SequenceOfShape.hxx> |
31 | #include <ShapeExtend_WireData.hxx> |
32 | #include <ShapeBuild_ReShape.hxx> |
33 | #include <Precision.hxx> |
34 | #include <TopoDS_Edge.hxx> |
35 | #include <TopTools_IndexedMapOfShape.hxx> |
b311480e |
36 | |
7fd59977 |
37 | //======================================================================= |
38 | //function : ShapeUpgrade_RemoveInternalWires |
39 | //purpose : |
40 | //======================================================================= |
41 | |
42 | ShapeUpgrade_RemoveInternalWires::ShapeUpgrade_RemoveInternalWires() |
43 | { |
44 | myMinArea =0.; |
45 | myRemoveFacesMode = Standard_True; |
46 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
47 | Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape; |
48 | SetContext(aContext); |
49 | |
50 | } |
51 | |
52 | //======================================================================= |
53 | //function : ShapeUpgrade_RemoveInternalWires |
54 | //purpose : |
55 | //======================================================================= |
56 | |
57 | ShapeUpgrade_RemoveInternalWires::ShapeUpgrade_RemoveInternalWires(const TopoDS_Shape& theShape) |
58 | { |
59 | Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape; |
60 | SetContext(aContext); |
61 | Init(theShape); |
62 | } |
63 | |
64 | //======================================================================= |
65 | //function : Init |
66 | //purpose : |
67 | //======================================================================= |
68 | |
69 | void ShapeUpgrade_RemoveInternalWires::Init(const TopoDS_Shape& theShape) |
70 | { |
71 | myShape = theShape; |
72 | Context()->Apply(theShape); |
73 | TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEdgeFaces); |
74 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
75 | myMinArea =0.; |
76 | myRemoveFacesMode = Standard_True; |
77 | } |
78 | |
79 | //======================================================================= |
80 | //function : Perform |
81 | //purpose : |
82 | //======================================================================= |
83 | |
84 | Standard_Boolean ShapeUpgrade_RemoveInternalWires::Perform() |
85 | { |
86 | Clear(); |
87 | if(myShape.IsNull()) { |
88 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); |
89 | return Standard_False; |
90 | } |
91 | TopExp_Explorer aExpF(myShape,TopAbs_FACE); |
92 | for( ; aExpF.More(); aExpF.Next()) { |
93 | TopoDS_Face aF = TopoDS::Face(aExpF.Current()); |
94 | removeSmallWire(aF,TopoDS_Wire()); |
95 | } |
96 | if(myRemoveFacesMode) |
97 | removeSmallFaces(); |
98 | |
99 | myResult = Context()->Apply(myShape); |
100 | return Status( ShapeExtend_DONE ); |
101 | } |
102 | |
103 | //======================================================================= |
104 | //function : Perform |
105 | //purpose : |
106 | //======================================================================= |
107 | |
108 | Standard_Boolean ShapeUpgrade_RemoveInternalWires::Perform(const TopTools_SequenceOfShape& theSeqShapes) |
109 | { |
110 | if(myShape.IsNull()) { |
111 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1); |
112 | return Standard_False; |
113 | } |
114 | Clear(); |
115 | TopTools_IndexedDataMapOfShapeListOfShape aWireFaces; |
116 | Standard_Integer i =1, nb = theSeqShapes.Length(); |
117 | for( ; i <= nb; i++) { |
118 | TopoDS_Shape aS = theSeqShapes.Value(i); |
119 | if(aS.ShapeType() == TopAbs_FACE) |
120 | removeSmallWire(aS,TopoDS_Wire()); |
121 | else if(aS.ShapeType() == TopAbs_WIRE) { |
122 | if(!aWireFaces.Extent()) |
123 | TopExp::MapShapesAndAncestors(myShape,TopAbs_WIRE,TopAbs_FACE,aWireFaces); |
124 | if(aWireFaces.Contains(aS)) { |
125 | const TopTools_ListOfShape& alfaces = aWireFaces.FindFromKey(aS); |
126 | TopTools_ListIteratorOfListOfShape liter(alfaces); |
127 | for( ; liter.More(); liter.Next()) |
128 | removeSmallWire(liter.Value(),aS); |
129 | } |
130 | |
131 | } |
132 | |
133 | } |
134 | if(myRemoveFacesMode) |
135 | removeSmallFaces(); |
136 | myResult = Context()->Apply(myShape); |
137 | return Status( ShapeExtend_DONE ); |
138 | } |
139 | |
140 | //======================================================================= |
141 | //function : removeSmallWire |
142 | //purpose : |
143 | //======================================================================= |
144 | |
145 | void ShapeUpgrade_RemoveInternalWires::removeSmallWire (const TopoDS_Shape& theFace, |
146 | const TopoDS_Shape& theWire) |
147 | { |
148 | TopoDS_Face aF = TopoDS::Face(theFace); |
149 | TopoDS_Wire anOutW = ShapeAnalysis::OuterWire(aF); |
150 | TopoDS_Iterator aIt(aF); |
151 | for( ; aIt.More(); aIt.Next()) { |
152 | if(aIt.Value().ShapeType() != TopAbs_WIRE || aIt.Value().IsSame(anOutW)) |
153 | continue; |
154 | //Handle(ShapeExtend_WireData) asewd = new ShapeExtend_WireData(); |
155 | TopoDS_Wire aW = TopoDS::Wire(aIt.Value()); |
156 | if(!theWire.IsNull() && !theWire.IsSame(aW)) |
157 | continue; |
158 | Standard_Real anArea = ShapeAnalysis::ContourArea(aW); |
159 | if(anArea < myMinArea -Precision::Confusion()) { |
160 | Context()->Remove(aW); |
161 | myRemoveWires.Append(aW); |
162 | myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE1); |
163 | if(!myRemoveFacesMode ) |
164 | continue; |
165 | |
166 | TopoDS_Iterator aIte(aW,Standard_False); |
167 | for( ; aIte.More(); aIte.Next()) { |
168 | TopoDS_Shape aE = aIte.Value(); |
169 | if(myRemoveEdges.IsBound(aE)) |
170 | myRemoveEdges.ChangeFind(aE).Append(aF); |
171 | else { |
172 | TopTools_ListOfShape alfaces; |
173 | alfaces.Append(aF); |
174 | myRemoveEdges.Bind(aE,alfaces); |
175 | } |
176 | } |
177 | } |
178 | |
179 | } |
180 | } |
181 | |
182 | //======================================================================= |
183 | //function : removeSmallFaces |
184 | //purpose : |
185 | //======================================================================= |
186 | |
187 | void ShapeUpgrade_RemoveInternalWires::removeSmallFaces () |
188 | { |
189 | |
190 | Standard_Integer i =1; |
191 | for( ; i <= myRemoveWires.Length() ; i++) { |
192 | TopoDS_Shape aWire = myRemoveWires.Value(i); |
193 | TopoDS_Iterator aIte(aWire,Standard_False); |
194 | TopTools_IndexedMapOfShape aFaceCandidates; |
195 | //collecting all faces containing edges from removed wire |
196 | for( ; aIte.More(); aIte.Next()) { |
197 | |
198 | TopoDS_Shape aEdge = aIte.Value(); |
199 | if(!myEdgeFaces.Contains(aEdge)) { |
200 | myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2); |
201 | continue; |
202 | } |
203 | const TopTools_ListOfShape& aLface1 = myEdgeFaces.FindFromKey(aEdge); |
204 | const TopTools_ListOfShape& aLface2 = myRemoveEdges.Find(aEdge); |
205 | TopTools_ListIteratorOfListOfShape aliter(aLface1); |
206 | TopTools_ListIteratorOfListOfShape aliter2(aLface2); |
207 | for( ; aliter.More(); aliter.Next()) { |
208 | TopoDS_Shape aF = Context()->Apply(aliter.Value()); |
209 | if(aF.IsNull()) |
210 | continue; |
211 | Standard_Boolean isFind = Standard_False; |
212 | for( ; aliter2.More() && !isFind; aliter2.Next()) { |
213 | TopoDS_Shape aF2 = Context()->Apply(aliter2.Value()); |
214 | isFind = aF.IsSame(aF2); |
215 | } |
216 | |
217 | if(!isFind) { |
218 | TopoDS_Wire aWout = ShapeAnalysis::OuterWire(TopoDS::Face(aF)); |
219 | Standard_Boolean isOuter = Standard_False; |
220 | TopoDS_Iterator aIter(aWout,Standard_False); |
221 | for( ; aIter.More() && !isOuter; aIter.Next()) |
222 | isOuter = aEdge.IsSame(aIter.Value()); |
223 | if(isOuter) |
224 | aFaceCandidates.Add(aF); |
225 | } |
226 | } |
227 | |
228 | } |
229 | |
230 | //remove faces which have outer wire consist of only |
231 | //edges from removed wires and |
232 | //seam edges for faces based on conic surface or |
233 | //in the case of a few faces based on the same conic surface |
234 | //the edges belogining these faces. |
235 | Standard_Integer k =1; |
236 | for( ; k <= aFaceCandidates.Extent(); k++) { |
237 | TopoDS_Shape aF = aFaceCandidates.FindKey(k); |
238 | TopoDS_Wire anOutW = ShapeAnalysis::OuterWire(TopoDS::Face(aF)); |
239 | Handle(ShapeExtend_WireData) asewd = new ShapeExtend_WireData(anOutW); |
240 | Standard_Integer n =1, nbE = asewd->NbEdges(); |
241 | Standard_Integer nbNotRemoved =0; |
242 | for( ; n <= nbE; n++) { |
243 | if(asewd->IsSeam(n)) |
244 | continue; |
245 | TopoDS_Edge aE = asewd->Edge(n); |
246 | if(!myRemoveEdges.IsBound(aE) ) { |
247 | const TopTools_ListOfShape& aLface3 = myEdgeFaces.FindFromKey(aE); |
248 | TopTools_ListIteratorOfListOfShape aliter3(aLface3); |
7fd59977 |
249 | for( ; aliter3.More();aliter3.Next()) { |
250 | TopoDS_Shape aF2 = Context()->Apply(aliter3.Value()); |
251 | if(aF2.IsNull()) |
252 | continue; |
253 | if(!aF.IsSame(aF2) && !aFaceCandidates.Contains(aF2)) |
254 | nbNotRemoved++; |
255 | } |
256 | } |
257 | |
258 | } |
259 | |
260 | if(!nbNotRemoved) { |
261 | Context()->Remove(aF); |
262 | myRemovedFaces.Append(aF); |
263 | } |
264 | } |
265 | } |
266 | |
267 | if(myRemovedFaces.Length()) |
268 | myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2); |
269 | } |
270 | |
271 | //======================================================================= |
272 | //function : Clear |
273 | //purpose : |
274 | //======================================================================= |
275 | |
276 | void ShapeUpgrade_RemoveInternalWires::Clear() |
277 | { |
278 | myRemoveEdges.Clear(); |
279 | myRemovedFaces.Clear(); |
280 | myRemoveWires.Clear(); |
281 | myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); |
282 | } |
283 | |