0026376: Imported STEP shape is partially wrong
[occt.git] / src / StepToTopoDS / StepToTopoDS_NMTool.cxx
1 // Created on: 2010-11-15
2 // Created by: Sergey SLYADNEV
3 // Copyright (c) 2010-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <StepToTopoDS_NMTool.hxx>
17 #include <TopTools_ListIteratorOfListOfShape.hxx>
18 #include <TopExp_Explorer.hxx>
19 #include <TopoDS_Shape.hxx>
20
21 // ============================================================================
22 // Method  : StepToTopoDS_NMTool
23 // Purpose : Default constructor
24 // ============================================================================
25
26 StepToTopoDS_NMTool::StepToTopoDS_NMTool() {
27   myIDEASCase = Standard_False;
28   myActiveFlag = Standard_False;
29 }
30
31 // ============================================================================
32 // Method  : StepToTopoDS_NMTool
33 // Purpose : Constructor with a Map for Representation Items and their names
34 // ============================================================================
35
36 StepToTopoDS_NMTool::StepToTopoDS_NMTool(const StepToTopoDS_DataMapOfRI& MapOfRI, 
37                                          const StepToTopoDS_DataMapOfRINames& MapOfRINames) {
38   myIDEASCase = Standard_False;
39   myActiveFlag = Standard_False;
40   Init(MapOfRI, MapOfRINames);
41 }
42
43 // ============================================================================
44 // Method  : Init
45 // Purpose : Initializes internal maps of the tool with the passed ones
46 // ============================================================================
47
48 void StepToTopoDS_NMTool::Init(const StepToTopoDS_DataMapOfRI& MapOfRI, 
49                                const StepToTopoDS_DataMapOfRINames& MapOfRINames) { 
50   myRIMap = MapOfRI;
51   myRINamesMap = MapOfRINames;
52 }
53
54 // ============================================================================
55 // Method  : SetActive
56 // Purpose : Turns the tool ON/OFF (OFF by default)
57 // ============================================================================
58
59 void StepToTopoDS_NMTool::SetActive(const Standard_Boolean isActive) {
60   myActiveFlag = isActive;
61 }
62
63 // ============================================================================
64 // Method  : IsActive
65 // Purpose : TRUE if active, FALSE - otherwise
66 // ============================================================================
67
68 Standard_Boolean StepToTopoDS_NMTool::IsActive() {
69   return myActiveFlag;
70 }
71
72 // ============================================================================
73 // Method  : CleanUp
74 // Purpose : Clears all internal containers
75 // ============================================================================
76
77 void StepToTopoDS_NMTool::CleanUp() { 
78   myRIMap.Clear();
79   myRINamesMap.Clear();
80 }
81
82 // ============================================================================
83 // Method  : IsBound
84 // Purpose : Indicates weither a RI is bound or not in the Map
85 // ============================================================================
86
87 Standard_Boolean StepToTopoDS_NMTool::IsBound(const Handle(StepRepr_RepresentationItem)& RI) {
88   return myRIMap.IsBound(RI);
89 }
90
91 // ============================================================================
92 // Method  : IsBound
93 // Purpose : Indicates weither a RI is bound or not in the Map by name
94 // ============================================================================
95
96 Standard_Boolean StepToTopoDS_NMTool::IsBound(const TCollection_AsciiString& RIName) {
97   return myRINamesMap.IsBound(RIName);
98 }
99
100 // ============================================================================
101 // Method  : Bind
102 // Purpose : Binds a RI with a Shape in the Map
103 // ============================================================================
104
105 void StepToTopoDS_NMTool::Bind(const Handle(StepRepr_RepresentationItem)& RI, const TopoDS_Shape& S) {
106   myRIMap.Bind(RI, S);
107 }
108
109 // ============================================================================
110 // Method  : Bind
111 // Purpose : Binds a RI's name with a Shape in the Map
112 // ============================================================================
113
114 void StepToTopoDS_NMTool::Bind(const TCollection_AsciiString& RIName, const TopoDS_Shape& S) {
115   myRINamesMap.Bind(RIName, S);
116 }
117
118 // ============================================================================
119 // Method  : Find
120 // Purpose : Returns the Shape corresponding to the bounded RI
121 // ============================================================================
122
123 const TopoDS_Shape& StepToTopoDS_NMTool::Find(const Handle(StepRepr_RepresentationItem)& RI) {
124   return myRIMap.Find(RI);
125 }
126
127 // ============================================================================
128 // Method  : Find
129 // Purpose : Returns the Shape corresponding to the bounded RI's name
130 // ============================================================================
131
132 const TopoDS_Shape& StepToTopoDS_NMTool::Find(const TCollection_AsciiString& RIName) {
133   return myRINamesMap.Find(RIName);
134 }
135
136 // ============================================================================
137 // Method  : RegisterNMEdge
138 // Purpose : Register non-manifold Edge in the internal storage if it wasn't
139 //           registered before
140 // ============================================================================
141
142 void StepToTopoDS_NMTool::RegisterNMEdge(const TopoDS_Shape& Edge) {
143   if ( !this->isEdgeRegisteredAsNM(Edge) )
144     myNMEdges.Append(Edge);
145 }
146
147 // ============================================================================
148 // Method  : IsSuspectedAsClosing
149 // Purpose : Checks whether SuspectedShell is pure non-manifold and adjacent
150 //           to BaseShell
151 // ============================================================================
152
153 Standard_Boolean StepToTopoDS_NMTool::IsSuspectedAsClosing(const TopoDS_Shape& BaseShell,
154                                                            const TopoDS_Shape& SuspectedShell) {
155   return this->IsPureNMShell(SuspectedShell) &&
156          this->isAdjacentShell(BaseShell, SuspectedShell);
157
158 }
159
160 // ============================================================================
161 // Method  : SetIDEASCase
162 // Purpose : Sets myIDEASCase flag (I-DEAS-like STP is processed)
163 // ============================================================================
164
165 void StepToTopoDS_NMTool::SetIDEASCase(const Standard_Boolean IDEASCase) {
166   myIDEASCase = IDEASCase;
167 }
168
169 // ============================================================================
170 // Method  : GetIDEASCase
171 // Purpose : Gets myIDEASCase flag (I-DEAS-like STP is processed)
172 // ============================================================================
173
174 Standard_Boolean StepToTopoDS_NMTool::IsIDEASCase() {
175   return myIDEASCase;
176 }
177
178 // ============================================================================
179 // Method  : IsPureNMShell
180 // Purpose : Checks if the Shell passed contains only non-manifold Edges
181 // ============================================================================
182
183 Standard_Boolean StepToTopoDS_NMTool::IsPureNMShell(const TopoDS_Shape& Shell) {
184   Standard_Boolean result = Standard_True;
185   TopExp_Explorer edgeExp(Shell, TopAbs_EDGE);
186   for ( ; edgeExp.More(); edgeExp.Next() ) {
187     TopoDS_Shape currentEdge = edgeExp.Current();
188     if ( !this->isEdgeRegisteredAsNM(currentEdge) ) {
189       result = Standard_False;
190       break;
191     }    
192   }
193   return result;
194 }
195
196 // ============================================================================
197 // Method  : isEdgeRegisteredAsNM
198 // Purpose : Checks if the Edge passed is registered as non-manifold one
199 // ============================================================================
200
201 Standard_Boolean StepToTopoDS_NMTool::isEdgeRegisteredAsNM(const TopoDS_Shape& Edge) {
202   Standard_Boolean result = Standard_False;
203   TopTools_ListIteratorOfListOfShape it(myNMEdges);
204   for ( ; it.More(); it.Next() ) {
205     TopoDS_Shape currentShape = it.Value();
206     if ( currentShape.IsSame(Edge) ) {
207       result =  Standard_True;
208       break;
209     }
210   }
211   return result;
212 }
213
214 // ============================================================================
215 // Method  : isAdjacentShell
216 // Purpose : Checks if the ShellA is adjacent to the ShellB
217 // ============================================================================
218
219 Standard_Boolean StepToTopoDS_NMTool::isAdjacentShell(const TopoDS_Shape& ShellA,
220                                                       const TopoDS_Shape& ShellB) {
221   if ( ShellA.IsSame(ShellB) )
222     return Standard_False;
223
224   TopExp_Explorer edgeExpA(ShellA, TopAbs_EDGE);
225   for ( ; edgeExpA.More(); edgeExpA.Next() ) {
226     TopoDS_Shape currentEdgeA = edgeExpA.Current();
227     TopExp_Explorer edgeExpB(ShellB, TopAbs_EDGE);
228     for ( ; edgeExpB.More(); edgeExpB.Next() ) {
229       TopoDS_Shape currentEdgeB = edgeExpB.Current();
230       if ( currentEdgeA.IsSame(currentEdgeB) )
231         return Standard_True;
232     }  
233   }
234
235   return Standard_False;
236 }