0025418: Debug output to be limited to OCC development environment
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_ShapeDivide.cxx
1 // Created on: 1999-04-27
2 // Created by: Pavel DURANDIN
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
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 OCCT_DEBUG
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 }