1 // Created on: 1998-11-19
2 // Created by: Jean-Michel BOULCOURT
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRepTools_Substitution.hxx>
19 #include <Standard_ConstructionError.hxx>
20 #include <Standard_NullObject.hxx>
22 #include <TopExp_Explorer.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopOpeBRepTool_PurgeInternalEdges.hxx>
26 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
27 #include <TopTools_DataMapOfShapeListOfShape.hxx>
28 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
29 #include <TopTools_ListIteratorOfListOfShape.hxx>
30 #include <TopTools_ListOfShape.hxx>
31 #include <TopTools_MapOfShape.hxx>
33 //=======================================================================
34 //function : TopOpeBRepTool_PurgeInternalEdges
35 //purpose : Initializes some variables for the algorithm and perform
36 // the computation of the internal edges of the shape
37 //=======================================================================
38 TopOpeBRepTool_PurgeInternalEdges::TopOpeBRepTool_PurgeInternalEdges(const TopoDS_Shape& theShape,const Standard_Boolean PerformNow):myShape(theShape),myIsDone(Standard_False)
40 // if (theShape.ShapeType() != TopAbs_SHELL && theShape.ShapeType() != TopAbs_SOLID)
41 // throw Standard_ConstructionError("PurgeInternalEdges");
42 Standard_NullObject_Raise_if(theShape.IsNull(),"PurgeInternalEdges");
49 //=======================================================================
52 //=======================================================================
54 void TopOpeBRepTool_PurgeInternalEdges::Faces(TopTools_DataMapOfShapeListOfShape& theMapFacLstEdg)
61 theMapFacLstEdg = myMapFacLstEdg;
65 //=======================================================================
68 //=======================================================================
70 Standard_Integer TopOpeBRepTool_PurgeInternalEdges::NbEdges() const
73 Standard_NullObject_Raise_if(myShape.IsNull(),"PurgeInternalEdges : No Shape");
74 Standard_Integer nbedges = 0;
76 // if we have at least on internal (or external) edge to remove
77 if (myMapFacLstEdg.Extent() > 0) {
79 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itFacEdg;
80 // TopTools_ListIteratorOfListOfShape itEdg;
82 for (itFacEdg.Initialize(myMapFacLstEdg); itFacEdg.More(); itFacEdg.Next()) {
83 const TopoDS_Shape& facecur = itFacEdg.Key();
84 const TopTools_ListOfShape& LmapEdg = myMapFacLstEdg.Find(facecur);
86 nbedges += LmapEdg.Extent();
98 //=======================================================================
101 //=======================================================================
103 TopoDS_Shape& TopOpeBRepTool_PurgeInternalEdges::Shape()
106 Standard_NullObject_Raise_if(myShape.IsNull(),"PurgeInternalEdges : No Shape");
112 //=======================================================================
113 //function : BuildList
114 //purpose : Build the map of faces with the list of inernal edges.
115 //=======================================================================
117 void TopOpeBRepTool_PurgeInternalEdges::BuildList()
120 TopExp_Explorer ExpEdge;
121 TopAbs_Orientation orien;
124 //--------------------------------------------------------
125 // Step One : Build the map of the faces ancestor of edges
126 //--------------------------------------------------------
129 myMapEdgLstFac.Clear();
131 TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myMapEdgLstFac);
134 //----------------------------------------------------------------
135 // Step Two : Explore the map myMapFacLstEdg to keep only the internal
136 // or external edges which have no connex faces
137 //----------------------------------------------------------------
140 Standard_Boolean ToKeep;
141 Standard_Integer iEdg;
142 TopTools_ListIteratorOfListOfShape itFac,itFacToTreat;
143 TopTools_ListOfShape LstFacToTreat;
145 // for each edge of myMapEdgLstFac
146 for (iEdg = 1; iEdg <= myMapEdgLstFac.Extent(); iEdg++) {
147 const TopoDS_Shape& edgecur = myMapEdgLstFac.FindKey(iEdg);
148 const TopTools_ListOfShape& LmapFac = myMapEdgLstFac.FindFromKey(edgecur);
151 // if there are more than on face connex to the edge then examine the orientation of
152 // the edge in the faces to see it is only Internal or External. In that case the edge
155 itFac.Initialize(LmapFac);
156 LstFacToTreat.Clear();
158 if (LmapFac.Extent() > 1) {
160 ToKeep = Standard_False;
161 // for each face in the list of the edge
162 while (itFac.More() && !ToKeep) {
163 const TopoDS_Shape& facecur = itFac.Value();
165 // find the edge in the face to get its relative orientation to the face
166 for (ExpEdge.Init(facecur,TopAbs_EDGE); ExpEdge.More(); ExpEdge.Next()) {
167 const TopoDS_Shape& edge = ExpEdge.Current();
169 orien = edge.Orientation();
171 if (edge.IsSame(edgecur)) {
172 // we found the edge. Now check if its orientation is internal or external
173 // then the face is candidate to be modified. So put it in a temporary List of shapes
174 if (orien == TopAbs_INTERNAL || orien == TopAbs_EXTERNAL) {
175 LstFacToTreat.Append(facecur);
178 // there is at least one face that contains that edge with a forward
179 // or reversed orientation. So we must keep that edge.
180 LstFacToTreat.Clear();
181 ToKeep = Standard_True;
193 if (edgecur.Orientation() == TopAbs_INTERNAL || edgecur.Orientation() == TopAbs_EXTERNAL) {
194 LstFacToTreat.Append(itFac.Value());
198 // at that point, we have in the list LstFacToTreat the faces in which edgecur is
199 // connex and is coded only Internal or External.
200 if (!LstFacToTreat.IsEmpty()) {
201 TopTools_MapOfShape mapUniqEdg;
202 for (itFacToTreat.Initialize(LstFacToTreat); itFacToTreat.More(); itFacToTreat.Next()) {
203 const TopoDS_Shape& face = itFacToTreat.Value();
205 //we build the resulting map with a face as a key and a list of internal (or external)
206 // edges to remove from the face.
207 if (!myMapFacLstEdg.IsBound(face)) {
208 TopTools_ListOfShape LmapEdg;
209 if (!mapUniqEdg.Contains(edgecur)) {
210 mapUniqEdg.Add(edgecur);
211 LmapEdg.Append(edgecur);
212 myMapFacLstEdg.Bind(face,LmapEdg);
215 else { // just append the edge to the list of edges of the face
216 TopTools_ListOfShape& LmapEdg = myMapFacLstEdg.ChangeFind(face);
217 if (!mapUniqEdg.Contains(edgecur)) {
218 mapUniqEdg.Add(edgecur);
219 LmapEdg.Append(edgecur);
228 myIsDone = Standard_True;
234 //=======================================================================
237 //=======================================================================
239 void TopOpeBRepTool_PurgeInternalEdges::Perform()
242 // if the list has not been yet built then do it
247 // if we have at least on internal (or external) edge to remove
248 if (myMapFacLstEdg.Extent() > 0) {
250 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itFacEdg;
251 TopTools_ListIteratorOfListOfShape itEdg;
252 TopTools_ListOfShape EmptyList;
253 BRepTools_Substitution Bsub;
255 for (itFacEdg.Initialize(myMapFacLstEdg); itFacEdg.More(); itFacEdg.Next()) {
256 const TopoDS_Shape& facecur = itFacEdg.Key();
257 const TopTools_ListOfShape& LmapEdg = myMapFacLstEdg.Find(facecur);
259 for (itEdg.Initialize(LmapEdg); itEdg.More(); itEdg.Next()) {
260 Bsub.Substitute(itEdg.Value(),EmptyList);
265 if (Bsub.IsCopied(myShape)) {
266 myShape=(Bsub.Copy(myShape)).First();