b311480e |
1 | // Created on: 1999-04-27 |
2 | // Created by: Pavel DURANDIN |
3 | // Copyright (c) 1999-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
973c2be1 |
8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public 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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
7fd59977 |
17 | // abv 16.06.99 returning ReShape context; processing shared subshapes in compounds |
18 | // sln 29.11.01 Bug21: in method Perform(..) nullify location of compound's faces only if mode myConsiderLocation is on |
19 | |
20 | #include <ShapeUpgrade_ShapeDivide.ixx> |
21 | #include <Precision.hxx> |
22 | #include <ShapeExtend.hxx> |
23 | #include <ShapeBuild_ReShape.hxx> |
24 | #include <TopExp_Explorer.hxx> |
25 | #include <TopExp.hxx> |
26 | #include <TopoDS.hxx> |
27 | #include <TopoDS_Edge.hxx> |
28 | #include <TopoDS_Wire.hxx> |
29 | #include <TopoDS_Compound.hxx> |
30 | #include <TopoDS_Iterator.hxx> |
31 | #include <TopoDS_Vertex.hxx> |
32 | #include <BRep_Builder.hxx> |
33 | #include <ShapeUpgrade_WireDivide.hxx> |
34 | #include <Standard_ErrorHandler.hxx> |
35 | #include <Standard_Failure.hxx> |
36 | |
37 | //======================================================================= |
38 | //function : ShapeUpgrade_ShapeDivide |
39 | //purpose : |
40 | //======================================================================= |
41 | |
42 | ShapeUpgrade_ShapeDivide::ShapeUpgrade_ShapeDivide() : myStatus(0) |
43 | { |
44 | myPrecision = myMinTol = Precision::Confusion(); |
45 | myMaxTol = 1; //Precision::Infinite() ?? pdn |
46 | mySplitFaceTool = new ShapeUpgrade_FaceDivide; |
47 | myContext = new ShapeBuild_ReShape; |
48 | mySegmentMode = Standard_True; |
49 | myEdgeMode = 2; |
50 | } |
51 | |
52 | //======================================================================= |
53 | //function : ShapeUpgrade_ShapeDivide |
54 | //purpose : |
55 | //======================================================================= |
56 | |
57 | ShapeUpgrade_ShapeDivide::ShapeUpgrade_ShapeDivide(const TopoDS_Shape &S) : myStatus(0) |
58 | { |
59 | myPrecision = myMinTol = Precision::Confusion(); |
60 | myMaxTol = 1; //Precision::Infinite() ?? pdn |
61 | mySplitFaceTool = new ShapeUpgrade_FaceDivide; |
62 | myContext = new ShapeBuild_ReShape; |
63 | mySegmentMode = Standard_True; |
64 | myEdgeMode = 2; |
65 | Init(S); |
66 | } |
67 | |
68 | //======================================================================= |
69 | //function : Init |
70 | //purpose : |
71 | //======================================================================= |
72 | |
73 | void ShapeUpgrade_ShapeDivide::Init(const TopoDS_Shape &S) |
74 | { |
75 | myShape = S; |
76 | } |
77 | |
78 | //======================================================================= |
79 | //function : Delete |
80 | //purpose : |
81 | //======================================================================= |
82 | |
83 | void ShapeUpgrade_ShapeDivide::Delete() |
84 | {} |
85 | |
86 | |
87 | //======================================================================= |
88 | //function : SetPrecision |
89 | //purpose : |
90 | //======================================================================= |
91 | |
92 | void ShapeUpgrade_ShapeDivide::SetPrecision (const Standard_Real Prec) |
93 | { |
94 | myPrecision = Prec; |
95 | } |
96 | |
97 | //======================================================================= |
98 | //function : SetMaxTolerance |
99 | //purpose : |
100 | //======================================================================= |
101 | |
102 | void ShapeUpgrade_ShapeDivide::SetMaxTolerance (const Standard_Real maxtol) |
103 | { |
104 | myMaxTol = maxtol; |
105 | } |
106 | |
107 | |
108 | //======================================================================= |
109 | //function : SetMinTolerance |
110 | //purpose : |
111 | //======================================================================= |
112 | |
113 | void ShapeUpgrade_ShapeDivide::SetMinTolerance (const Standard_Real mintol) |
114 | { |
115 | myMinTol = mintol; |
116 | } |
117 | |
118 | |
119 | //======================================================================= |
120 | //function : SetSurfaceSegmentMode |
121 | //purpose : |
122 | //======================================================================= |
123 | |
124 | void ShapeUpgrade_ShapeDivide::SetSurfaceSegmentMode(const Standard_Boolean Segment) |
125 | { |
126 | mySegmentMode = Segment; |
127 | } |
128 | //======================================================================= |
129 | //function : Perform |
130 | //purpose : |
131 | //======================================================================= |
132 | |
133 | Standard_Boolean ShapeUpgrade_ShapeDivide::Perform(const Standard_Boolean newContext) |
134 | { |
135 | myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK ); |
136 | if(myShape.IsNull()) { |
137 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); |
138 | return Standard_False; |
139 | } |
140 | |
141 | if ( newContext || myContext.IsNull() ) |
142 | myContext = new ShapeBuild_ReShape; |
143 | |
144 | // Process COMPOUNDs separately in order to handle sharing in assemblies |
145 | // NOTE: not optimized: subshape can be processed twice (second time - no modif) |
146 | if ( myShape.ShapeType() == TopAbs_COMPOUND ) { |
147 | Standard_Integer locStatus = myStatus; |
148 | TopoDS_Compound C; |
149 | BRep_Builder B; |
150 | B.MakeCompound ( C ); |
151 | TopoDS_Shape savShape = myShape; |
152 | for ( TopoDS_Iterator it(savShape,Standard_False); it.More(); it.Next() ) { |
153 | TopoDS_Shape shape = it.Value(); |
154 | TopLoc_Location L = shape.Location(); |
155 | if(myContext->ModeConsiderLocation()) { |
156 | TopLoc_Location nullLoc; |
157 | shape.Location ( nullLoc ); |
158 | } |
159 | myShape = myContext->Apply ( shape ); |
160 | Perform ( Standard_False ); |
161 | if(myContext->ModeConsiderLocation()) |
162 | myResult.Location ( L ); |
163 | myResult.Orientation(TopAbs::Compose(myResult.Orientation(),savShape.Orientation())); |
164 | B.Add ( C, myResult ); |
165 | locStatus |= myStatus; |
166 | } |
167 | |
168 | myShape = savShape; |
169 | myStatus = locStatus; |
170 | if ( Status ( ShapeExtend_DONE ) ) { |
171 | myResult = myContext->Apply ( C, TopAbs_SHAPE ); |
172 | myContext->Replace ( myShape, myResult ); |
173 | return Standard_True; |
174 | } |
175 | myResult = myShape; |
176 | return Standard_False; |
177 | } |
178 | |
179 | // Process FACEs |
180 | Handle(ShapeUpgrade_FaceDivide) SplitFace = GetSplitFaceTool(); |
181 | if ( ! SplitFace.IsNull() ) { |
182 | SplitFace->SetPrecision( myPrecision ); |
183 | SplitFace->SetMaxTolerance(myMaxTol); |
184 | SplitFace->SetSurfaceSegmentMode(mySegmentMode); |
185 | Handle(ShapeUpgrade_WireDivide) SplitWire = SplitFace->GetWireDivideTool(); |
186 | if ( ! SplitWire.IsNull() ) { |
187 | SplitWire->SetMinTolerance(myMinTol); |
188 | SplitWire->SetEdgeMode(myEdgeMode); |
189 | } |
190 | for(TopExp_Explorer exp(myShape,TopAbs_FACE); exp.More(); exp.Next()) { |
191 | //smh#8 |
192 | TopoDS_Shape tmpF = exp.Current().Oriented ( TopAbs_FORWARD ); |
193 | TopoDS_Face F = TopoDS::Face (tmpF); // protection against INTERNAL shapes: cts20105a.rle |
194 | TopoDS_Shape sh = myContext->Apply ( F, TopAbs_SHAPE ); |
195 | for (TopExp_Explorer exp2(sh,TopAbs_FACE); exp2.More(); exp2.Next()) { |
196 | //szv: try-catch added |
197 | try { |
198 | OCC_CATCH_SIGNALS |
199 | for (; exp2.More(); exp2.Next()) { |
200 | TopoDS_Face face = TopoDS::Face ( exp2.Current() ); |
201 | SplitFace->Init(face); |
202 | SplitFace->SetContext(myContext); |
203 | SplitFace->Perform(); |
204 | if(SplitFace->Status(ShapeExtend_FAIL)) { |
205 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); |
206 | } |
207 | if(SplitFace->Status(ShapeExtend_DONE)) { |
208 | myContext->Replace(face,SplitFace->Result()); |
209 | if(SplitFace->Status(ShapeExtend_DONE1)) |
210 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
211 | if(SplitFace->Status(ShapeExtend_DONE2)) |
212 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); |
213 | } |
214 | } |
215 | } |
216 | catch (Standard_Failure) { |
217 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); |
218 | #ifdef DEB |
219 | cout << "\nError: Exception in ShapeUpgrade_FaceDivide::Perform(): "; |
220 | Standard_Failure::Caught()->Print(cout); cout << endl; |
221 | #endif |
222 | } |
223 | } |
224 | } |
225 | } |
226 | |
227 | // Process free WIREs |
228 | Handle(ShapeUpgrade_WireDivide) SplitWire = SplitFace->GetWireDivideTool(); |
229 | if ( ! SplitWire.IsNull() ) { |
230 | SplitWire->SetFace (TopoDS_Face()); |
231 | SplitWire->SetPrecision( myPrecision ); |
232 | SplitWire->SetMaxTolerance(myMaxTol); |
233 | SplitWire->SetMinTolerance(myMinTol); |
234 | SplitWire->SetEdgeMode(myEdgeMode); |
235 | TopExp_Explorer exp;//svv Jan 10 2000 : porting on DEC |
236 | for (exp.Init (myShape, TopAbs_WIRE, TopAbs_FACE); exp.More(); exp.Next()) { |
237 | //smh#8 |
238 | TopoDS_Shape tmpW = exp.Current().Oriented ( TopAbs_FORWARD ); |
239 | TopoDS_Wire W = TopoDS::Wire (tmpW ); // protection against INTERNAL shapes |
240 | TopoDS_Shape sh = myContext->Apply ( W, TopAbs_SHAPE ); |
241 | for (TopExp_Explorer exp2 (sh,TopAbs_WIRE); exp2.More(); exp2.Next()) { |
242 | TopoDS_Wire wire = TopoDS::Wire ( exp2.Current() ); |
243 | SplitWire->Load (wire); |
244 | SplitWire->SetContext(myContext); |
245 | SplitWire->Perform(); |
246 | if(SplitWire->Status(ShapeExtend_FAIL)) { |
247 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 ); |
248 | } |
249 | if(SplitWire->Status(ShapeExtend_DONE)) { |
250 | myContext->Replace(wire,SplitWire->Wire()); |
251 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
252 | } |
253 | } |
254 | } |
255 | |
256 | // Process free EDGEs |
257 | for (exp.Init (myShape, TopAbs_EDGE, TopAbs_WIRE); exp.More(); exp.Next()) { |
258 | //smh#8 |
259 | TopoDS_Shape tmpE = exp.Current().Oriented ( TopAbs_FORWARD ); |
260 | TopoDS_Edge E = TopoDS::Edge (tmpE ); // protection against INTERNAL shapes |
261 | TopoDS_Vertex V1,V2; |
262 | TopExp::Vertices(E,V2,V1); |
263 | if( V1.IsNull() && V2.IsNull() ) continue; // skl 27.10.2004 for OCC5624 |
264 | TopoDS_Shape sh = myContext->Apply ( E, TopAbs_SHAPE ); |
265 | for (TopExp_Explorer exp2 (sh,TopAbs_EDGE); exp2.More(); exp2.Next()) { |
266 | TopoDS_Edge edge = TopoDS::Edge ( exp2.Current() ); |
267 | SplitWire->Load (edge); |
268 | SplitWire->SetContext(myContext); |
269 | SplitWire->Perform(); |
270 | if(SplitWire->Status(ShapeExtend_FAIL)) { |
271 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 ); |
272 | } |
273 | if(SplitWire->Status(ShapeExtend_DONE)) { |
274 | myContext->Replace(edge,SplitWire->Wire()); |
275 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); |
276 | } |
277 | } |
278 | } |
279 | } |
280 | myResult = myContext->Apply ( myShape, TopAbs_SHAPE ); |
281 | return ! myResult.IsSame ( myShape ); |
282 | } |
283 | |
284 | //======================================================================= |
285 | //function : Result |
286 | //purpose : |
287 | //======================================================================= |
288 | |
289 | TopoDS_Shape ShapeUpgrade_ShapeDivide::Result() const |
290 | { |
291 | return myResult; |
292 | } |
293 | |
294 | //======================================================================= |
295 | //function : GetContext |
296 | //purpose : |
297 | //======================================================================= |
298 | |
299 | Handle(ShapeBuild_ReShape) ShapeUpgrade_ShapeDivide::GetContext() const |
300 | { |
301 | //if ( myContext.IsNull() ) myContext = new ShapeBuild_ReShape; |
302 | return myContext; |
303 | } |
304 | |
305 | //======================================================================= |
306 | //function : SetContext |
307 | //purpose : |
308 | //======================================================================= |
309 | |
310 | void ShapeUpgrade_ShapeDivide::SetContext (const Handle(ShapeBuild_ReShape) &context) |
311 | { |
312 | myContext = context; |
313 | } |
314 | |
315 | //======================================================================= |
316 | //function : SetSplitFaceTool |
317 | //purpose : |
318 | //======================================================================= |
319 | |
320 | void ShapeUpgrade_ShapeDivide::SetSplitFaceTool(const Handle(ShapeUpgrade_FaceDivide)& splitFaceTool) |
321 | { |
322 | mySplitFaceTool = splitFaceTool; |
323 | } |
324 | |
325 | //======================================================================= |
326 | //function : GetSplitFaceTool |
327 | //purpose : |
328 | //======================================================================= |
329 | |
330 | Handle(ShapeUpgrade_FaceDivide) ShapeUpgrade_ShapeDivide::GetSplitFaceTool () const |
331 | { |
332 | return mySplitFaceTool; |
333 | } |
334 | |
335 | //======================================================================= |
336 | //function : Status |
337 | //purpose : |
338 | //======================================================================= |
339 | |
340 | Standard_Boolean ShapeUpgrade_ShapeDivide::Status (const ShapeExtend_Status status) const |
341 | { |
342 | return ShapeExtend::DecodeStatus ( myStatus, status ); |
343 | } |
344 | |
345 | //======================================================================= |
346 | //function : SetEdgeMode |
347 | //purpose : |
348 | //======================================================================= |
349 | |
350 | void ShapeUpgrade_ShapeDivide::SetEdgeMode(const Standard_Integer aEdgeMode) |
351 | { |
352 | myEdgeMode = aEdgeMode; |
353 | } |