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