1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <ShapeUpgrade_RemoveInternalWires.ixx>
15 #include <TopExp_Explorer.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>
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>
33 //=======================================================================
34 //function : ShapeUpgrade_RemoveInternalWires
36 //=======================================================================
38 ShapeUpgrade_RemoveInternalWires::ShapeUpgrade_RemoveInternalWires()
41 myRemoveFacesMode = Standard_True;
42 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
43 Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
48 //=======================================================================
49 //function : ShapeUpgrade_RemoveInternalWires
51 //=======================================================================
53 ShapeUpgrade_RemoveInternalWires::ShapeUpgrade_RemoveInternalWires(const TopoDS_Shape& theShape)
55 Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
60 //=======================================================================
63 //=======================================================================
65 void ShapeUpgrade_RemoveInternalWires::Init(const TopoDS_Shape& theShape)
68 Context()->Apply(theShape);
69 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myEdgeFaces);
70 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
72 myRemoveFacesMode = Standard_True;
75 //=======================================================================
78 //=======================================================================
80 Standard_Boolean ShapeUpgrade_RemoveInternalWires::Perform()
83 if(myShape.IsNull()) {
84 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
85 return Standard_False;
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());
95 myResult = Context()->Apply(myShape);
96 return Status( ShapeExtend_DONE );
99 //=======================================================================
102 //=======================================================================
104 Standard_Boolean ShapeUpgrade_RemoveInternalWires::Perform(const TopTools_SequenceOfShape& theSeqShapes)
106 if(myShape.IsNull()) {
107 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
108 return Standard_False;
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);
130 if(myRemoveFacesMode)
132 myResult = Context()->Apply(myShape);
133 return Status( ShapeExtend_DONE );
136 //=======================================================================
137 //function : removeSmallWire
139 //=======================================================================
141 void ShapeUpgrade_RemoveInternalWires::removeSmallWire (const TopoDS_Shape& theFace,
142 const TopoDS_Shape& theWire)
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))
150 //Handle(ShapeExtend_WireData) asewd = new ShapeExtend_WireData();
151 TopoDS_Wire aW = TopoDS::Wire(aIt.Value());
152 if(!theWire.IsNull() && !theWire.IsSame(aW))
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 )
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);
168 TopTools_ListOfShape alfaces;
170 myRemoveEdges.Bind(aE,alfaces);
178 //=======================================================================
179 //function : removeSmallFaces
181 //=======================================================================
183 void ShapeUpgrade_RemoveInternalWires::removeSmallFaces ()
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()) {
194 TopoDS_Shape aEdge = aIte.Value();
195 if(!myEdgeFaces.Contains(aEdge)) {
196 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
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());
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);
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());
220 aFaceCandidates.Add(aF);
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++) {
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());
249 if(!aF.IsSame(aF2) && !aFaceCandidates.Contains(aF2))
257 Context()->Remove(aF);
258 myRemovedFaces.Append(aF);
263 if(myRemovedFaces.Length())
264 myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_DONE2);
267 //=======================================================================
270 //=======================================================================
272 void ShapeUpgrade_RemoveInternalWires::Clear()
274 myRemoveEdges.Clear();
275 myRemovedFaces.Clear();
276 myRemoveWires.Clear();
277 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);