0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / BRepTools / BRepTools_ReShape.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //    abv 28.04.99 S4137: ading method Apply for work on all types of shapes
15 //    sln 29.11.01 Bug24: correction iteration through map in method 'Status'
16 //    sln 29.11.01 Bug22: correction of methods Replace and Value for case when mode myConsiderLocation is on
17
18 #include <BRep_Builder.hxx>
19 #include <BRep_GCurve.hxx>
20 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21 #include <BRep_ListOfCurveRepresentation.hxx>
22 #include <BRep_TEdge.hxx>
23 #include <BRep_Tool.hxx>
24 #include <BRepTools_ReShape.hxx>
25 #include <Geom_Surface.hxx>
26 #include <NCollection_IndexedMap.hxx>
27 #include <Standard_Type.hxx>
28 #include <TopExp_Explorer.hxx>
29 #include <TopLoc_Location.hxx>
30 #include <TopoDS.hxx>
31 #include <TopoDS_Compound.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Solid.hxx>
38
39 IMPLEMENT_STANDARD_RTTIEXT(BRepTools_ReShape,Standard_Transient)
40
41 namespace
42 {
43
44 //! Adds the shape to the map.
45 //! If the shape is a wire, shell or solid then
46 //! adds the sub-shapes of the shape instead.
47 //! Returns 'true' if the sub-shapes were added.
48 template<typename TMap>
49 void Add(TMap& theMap, const TopoDS_Shape& theShape)
50 {
51   const TopAbs_ShapeEnum aType = theShape.ShapeType();
52   if (aType != TopAbs_WIRE && aType != TopAbs_SHELL &&
53     aType != TopAbs_COMPSOLID)
54   {
55     theMap.Add(theShape);
56     return;
57   }
58
59   for (TopoDS_Iterator aIt(theShape); aIt.More(); aIt.Next())
60   {
61     theMap.Add(aIt.Value());
62   }
63 }
64
65 }
66
67 //include <ShapeExtend.hxx>
68 //#include <BRepTools_Edge.hxx>
69 static void CopyRanges (const TopoDS_Shape& toedge, const TopoDS_Shape& fromedge,
70                         const Standard_Real alpha, const Standard_Real beta) 
71 {
72   Handle(BRep_TEdge) aTEdgeFrom = Handle(BRep_TEdge)::DownCast(fromedge.TShape());
73   Handle(BRep_TEdge) aTEdgeTo   = Handle(BRep_TEdge)::DownCast(toedge.TShape());
74   BRep_ListOfCurveRepresentation& tolist = aTEdgeTo->ChangeCurves();
75   BRep_ListIteratorOfListOfCurveRepresentation fromitcr (aTEdgeFrom->ChangeCurves());
76   for (; fromitcr.More(); fromitcr.Next()) {
77     Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
78     if ( fromGC.IsNull() ) continue;
79     Standard_Boolean isC3d = fromGC->IsCurve3D();
80     if(isC3d) {
81       if(fromGC->Curve3D().IsNull()) continue; }
82     else {
83        if(fromGC->PCurve().IsNull()) continue; }
84       
85     if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated
86
87     Handle(Geom_Surface) surface;
88     TopLoc_Location L;
89     if ( ! isC3d ) {
90       surface = fromGC->Surface();
91       L = fromGC->Location();
92     } 
93
94     Handle(BRep_GCurve) toGC;
95     for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) {
96       toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
97       if ( toGC.IsNull() ) continue;
98       if ( isC3d ) {
99         if ( ! toGC->IsCurve3D() ) continue;
100       }
101       else if ( ! toGC->IsCurveOnSurface() || 
102                surface != toGC->Surface() || L != toGC->Location() ) continue;
103       Standard_Real first = fromGC->First();
104       Standard_Real last = fromGC->Last();
105       Standard_Real len = last - first;
106       toGC->SetRange ( first+alpha*len, first+beta*len );
107       break;
108     }
109   }
110 }
111
112
113 //=======================================================================
114 //function : BRepTools_ReShape
115 //purpose  : 
116 //=======================================================================
117
118 BRepTools_ReShape::BRepTools_ReShape()
119 : myStatus(-1)
120 {
121   myConsiderLocation = Standard_False;
122 }
123
124
125 //=======================================================================
126 //function : Clear
127 //purpose  : 
128 //=======================================================================
129
130 void BRepTools_ReShape::Clear() 
131 {
132   myShapeToReplacement.Clear();
133   myNewShapes.Clear();
134 }
135
136
137 //=======================================================================
138 //function : Remove
139 //purpose  : 
140 //=======================================================================
141
142 void BRepTools_ReShape::Remove (const TopoDS_Shape& shape)
143 {
144   TopoDS_Shape nulshape;
145   replace(shape, nulshape, TReplacementKind_Remove);
146 }
147
148 //=======================================================================
149 //function : replace
150 //purpose  : 
151 //=======================================================================
152
153 void BRepTools_ReShape::replace (const TopoDS_Shape& ashape,
154                                  const TopoDS_Shape& anewshape,
155                                  const TReplacementKind theKind)
156 {
157   TopoDS_Shape shape = ashape;
158   TopoDS_Shape newshape = anewshape;
159   if ( shape.IsNull() || shape == newshape ) return;
160
161   if (shape.Orientation() == TopAbs_REVERSED)
162   {
163     shape.Reverse();
164     newshape.Reverse();
165   }
166   // protect against INTERNAL or EXTERNAL shape
167   else if (shape.Orientation() == TopAbs_INTERNAL
168     || shape.Orientation() == TopAbs_EXTERNAL)
169   {
170     newshape.Orientation((newshape.Orientation() == shape.Orientation()) ?
171       TopAbs_FORWARD : TopAbs_REVERSED);
172     shape.Orientation(TopAbs_FORWARD);
173   }
174
175   if (myConsiderLocation) {
176     //sln 29.11.01 Bug22: Change location of 'newshape' in accordance with location of 'shape'
177     newshape.Location(newshape.Location().Multiplied(shape.Location().Inverted()));
178     TopLoc_Location nullLoc; 
179     shape.Location ( nullLoc );
180   }
181
182 #ifdef OCCT_DEBUG
183   if ( IsRecorded ( shape ) && ((myConsiderLocation && ! Value ( shape ).IsPartner ( newshape )) ||
184                                  (!myConsiderLocation && ! Value ( shape ).IsSame ( newshape )))) 
185     std::cout << "Warning: BRepTools_ReShape::Replace: shape already recorded" << std::endl;
186 #endif
187
188   myShapeToReplacement.Bind(shape, TReplacement(newshape, theKind));
189   myNewShapes.Add (newshape);
190 }
191
192 //=======================================================================
193 //function : IsRecorded
194 //purpose  : 
195 //=======================================================================
196
197 Standard_Boolean BRepTools_ReShape::IsRecorded (const TopoDS_Shape& ashape) const
198 {
199   TopoDS_Shape shape = ashape;
200   if (myConsiderLocation) {
201     TopLoc_Location nullLoc;
202     shape.Location ( nullLoc );
203   }
204   if (shape.IsNull()) return Standard_False;
205   return myShapeToReplacement.IsBound (shape);
206 }
207
208
209 //=======================================================================
210 //function : Value
211 //purpose  : 
212 //=======================================================================
213
214 TopoDS_Shape BRepTools_ReShape::Value (const TopoDS_Shape& ashape) const
215 {
216   TopoDS_Shape res;
217   if (ashape.IsNull()) return res;
218   TopoDS_Shape shape = ashape;
219   if (myConsiderLocation) {
220     TopLoc_Location nullLoc;
221     shape.Location ( nullLoc );
222   }
223   
224   Standard_Boolean fromMap = Standard_False;
225   if (!myShapeToReplacement.IsBound(shape))
226   {
227     res = shape;
228   }
229   else
230   {
231     res = myShapeToReplacement(shape).Result();
232     if (shape.Orientation() == TopAbs_REVERSED)
233     {
234       res.Reverse();
235     }
236     fromMap = Standard_True;
237   }
238   // for INTERNAL/EXTERNAL, since they are not fully supported, keep orientation
239   if ( shape.Orientation() == TopAbs_INTERNAL ||
240        shape.Orientation() == TopAbs_EXTERNAL ) 
241     res.Orientation ( shape.Orientation() );
242
243   if (myConsiderLocation) {
244     //sln 29.11.01 Bug22: Recalculate location of resulting shape in accordance with
245     //whether result is from map or not
246     if(fromMap) res.Location(ashape.Location()*res.Location());
247     else res.Location(ashape.Location());
248   }
249
250   return res;
251 }
252
253
254 //=======================================================================
255 //function : Status
256 //purpose  : 
257 //=======================================================================
258
259 Standard_Integer BRepTools_ReShape::Status(const TopoDS_Shape& ashape,
260                                             TopoDS_Shape& newsh,
261                                             const Standard_Boolean last) 
262 {
263   Standard_Integer res = 0;
264   if (ashape.IsNull())  {  newsh.Nullify();  return res;  }
265
266   TopoDS_Shape shape = ashape;
267   TopLoc_Location aLocSh = shape.Location();
268   if (myConsiderLocation) {
269     TopLoc_Location nullLoc;
270     shape.Location ( nullLoc );
271   }
272
273   if (!myShapeToReplacement.IsBound(shape))
274   {
275     newsh = shape;
276     res = 0;
277   }
278   else
279   {
280     newsh = myShapeToReplacement(shape).Result();
281     res = 1;
282   }
283   if (res > 0) {
284     if (newsh.IsNull()) res = -1;
285     else if (newsh.IsEqual (shape)) res = 0;
286     else if ( last && ((myConsiderLocation && ! newsh.IsPartner (shape)) ||
287                        (!myConsiderLocation && ! newsh.IsSame (shape)))) {
288       //TopoDS_Shape newnewsh;
289       //Standard_Integer newres = Status (newsh, newnewsh, last);
290       //newsh = newnewsh;
291       //if (newres) res = newres;
292       // sln 29.11.01 Bug24: Correction iteration through maps. Way of iteration used early does not
293       // correspond to way of storing information in the maps.
294       newsh = Apply(shape, TopAbs_SHAPE);
295       if (newsh.IsNull()) res = -1; 
296       if (newsh.IsEqual (shape)) res = 0;
297     }
298   }
299   if(myConsiderLocation && !newsh.IsNull()) 
300   {
301     TopLoc_Location aResLoc = (res >0 && !newsh.Location().IsIdentity() ? 
302       aLocSh * newsh.Location() : aLocSh);
303     newsh.Location(aResLoc);
304   }
305   return res;
306 }
307
308 //=======================================================================
309 //function : EncodeStatus
310 //purpose  : static
311 //=======================================================================
312 static Standard_Integer EncodeStatus (const Standard_Integer status)
313 {
314   switch ( status ) {
315   case 0   : return 0x0000; //ShapeExtend_OK
316   case 1: return 0x0001;    //ShapeExtend_DONE1
317   case 2: return 0x0002;    //....
318   case 3: return 0x0004;
319   case 4: return 0x0008;
320   case 5: return 0x0010;
321   case 6: return 0x0020;
322   case 7: return 0x0040;
323   case 8: return 0x0080;    //....
324   case 9 : return 0x00ff;   //ShapeExtend_DONE
325   case 10: return 0x0100;   //ShapeExtend_FAIL1
326   case 11: return 0x0200;   //...
327   case 12: return 0x0400;
328   case 13: return 0x0800;
329   case 14: return 0x1000;
330   case 15: return 0x2000;
331   case 16: return 0x4000;
332   case 17: return 0x8000;   //....
333   case 18 : return 0xff00;  //ShapeExtend_FAIL
334   }
335   return 0;
336 }
337
338
339 //=======================================================================
340 //function : Apply
341 //purpose  : 
342 //=======================================================================
343
344 TopoDS_Shape BRepTools_ReShape::Apply (const TopoDS_Shape& shape,
345                                        const TopAbs_ShapeEnum until) 
346 {
347   myStatus = EncodeStatus(0); //ShapeExtend::EncodeStatus ( ShapeExtend_OK );
348   if ( shape.IsNull() ) return shape;
349
350   // apply direct replacement
351   TopoDS_Shape newsh = Value ( shape );
352   
353   // if shape removed, return NULL
354   if ( newsh.IsNull() ) {
355     myStatus = EncodeStatus (2); //ShapeExtend_DONE2
356     return newsh;
357   }
358   
359   // if shape replaced, apply modifications to the result recursively 
360   if ( (myConsiderLocation && ! newsh.IsPartner (shape)) || 
361       (!myConsiderLocation &&! newsh.IsSame ( shape )) ) {
362     TopoDS_Shape res = Apply ( newsh, until );
363     myStatus |= EncodeStatus(1); //ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
364     return res;
365   }
366
367   TopAbs_ShapeEnum st = shape.ShapeType();
368   if (st > until || (st == until && until > TopAbs_COMPOUND)) return newsh; // stopping criteria
369   if(st == TopAbs_VERTEX || st == TopAbs_SHAPE)
370     return shape;
371   // define allowed types of components
372   //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing. 
373   /*
374   switch ( st ) {
375   case TopAbs_COMPOUND:  subt = TopAbs_SHAPE;  break;
376   case TopAbs_COMPSOLID: subt = TopAbs_SOLID;  break;
377   case TopAbs_SOLID:     subt = TopAbs_SHELL;  break;
378   case TopAbs_SHELL:     subt = TopAbs_FACE;   break;
379   case TopAbs_FACE:      subt = TopAbs_WIRE;   break;
380   case TopAbs_WIRE:      subt = TopAbs_EDGE;   break;
381   case TopAbs_EDGE:      subt = TopAbs_VERTEX; break;
382   case TopAbs_VERTEX:
383   case TopAbs_SHAPE:
384   default:               return shape;
385   }
386   */
387   BRep_Builder B;
388   
389   TopoDS_Shape result = shape.EmptyCopied();
390   TopAbs_Orientation orien = shape.Orientation();
391   result.Orientation(TopAbs_FORWARD); // protect against INTERNAL or EXTERNAL shapes
392   Standard_Boolean modif = Standard_False;
393   Standard_Integer locStatus = myStatus;
394   
395   // apply recorded modifications to subshapes
396   Standard_Boolean isEmpty = Standard_True;
397   for ( TopoDS_Iterator it(shape,Standard_False); it.More(); it.Next() ) {
398     TopoDS_Shape sh = it.Value();
399     newsh = Apply ( sh, until );
400     if ( newsh != sh ) {
401       if ( myStatus & EncodeStatus(4)) //ShapeExtend::DecodeStatus ( myStatus, ShapeExtend_DONE4 ) )
402         locStatus |= EncodeStatus(4); //|= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
403       modif = 1;
404     }
405     if ( newsh.IsNull() ) {
406       locStatus |= EncodeStatus(4); //ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
407       continue;
408     }
409     if ( isEmpty )
410       isEmpty = Standard_False;
411     locStatus |= EncodeStatus(3);//ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
412     if ( st == TopAbs_COMPOUND || newsh.ShapeType() == sh.ShapeType()) { //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing.
413       B.Add ( result, newsh );
414       continue;
415     }
416     Standard_Integer nitems = 0;
417     for ( TopoDS_Iterator subit(newsh); subit.More(); subit.Next(), nitems++ ) {
418       TopoDS_Shape subsh = subit.Value();
419       if ( subsh.ShapeType() == sh.ShapeType() ) B.Add ( result, subsh );//fix for SAMTECH bug OCC322 about abcense internal vertices after sewing.
420       else locStatus |= EncodeStatus(10);//ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
421     }
422     if ( ! nitems ) locStatus |= EncodeStatus(10);//ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
423   }
424   if ( ! modif ) return shape;
425
426   // For empty topological containers (any kind of shape except vertex, edge
427   // and face) we have to produce an empty result
428   if ( isEmpty && st != TopAbs_VERTEX && st != TopAbs_EDGE && st != TopAbs_FACE )
429   {
430     result = TopoDS_Shape();
431   }
432   else
433   {
434     // restore Range on edge broken by EmptyCopied()
435     if ( st == TopAbs_EDGE ) {
436       CopyRanges (result, shape, 0, 1);
437     }
438     else if (st == TopAbs_FACE)  {
439       TopoDS_Face face = TopoDS::Face ( shape );
440       if( BRep_Tool::NaturalRestriction( face ) ) {
441         BRep_Builder aB;
442         aB.NaturalRestriction( TopoDS::Face (  result ), Standard_True );
443       }
444     }
445     else if (st == TopAbs_WIRE || st == TopAbs_SHELL)
446       result.Closed (BRep_Tool::IsClosed (result));
447
448     result.Orientation(orien);
449   }
450
451   replace(shape, result,
452     result.IsNull() ? TReplacementKind_Remove : TReplacementKind_Modify);
453   myStatus = locStatus;
454
455   return result;
456 }
457
458
459 //=======================================================================
460 //function : Status
461 //purpose  : 
462 //=======================================================================
463
464 /*Standard_Boolean BRepTools_ReShape::Status (const ShapeExtend_Status status) const
465 {
466   return ShapeExtend::DecodeStatus ( myStatus, status );
467 }*/
468
469 //=======================================================================
470 //function : CopyVertex
471 //purpose  : 
472 //=======================================================================
473
474 TopoDS_Vertex BRepTools_ReShape::CopyVertex(const TopoDS_Vertex& theV,
475                                             const Standard_Real theTol)
476 {
477   return CopyVertex(theV, BRep_Tool::Pnt(theV), theTol);
478 }
479
480 //=======================================================================
481 //function : CopyVertex
482 //purpose  : 
483 //=======================================================================
484
485 TopoDS_Vertex BRepTools_ReShape::CopyVertex(const TopoDS_Vertex& theV,
486                                             const gp_Pnt& theNewPos,
487                                             const Standard_Real theTol)
488 {
489   TopoDS_Vertex aVertexCopy;
490   Standard_Boolean isRecorded = IsRecorded(theV);
491   aVertexCopy = isRecorded ? TopoDS::Vertex(Apply(theV)) : TopoDS::Vertex(theV.EmptyCopied());
492
493   BRep_Builder B;
494   Standard_Real aNewTol = theTol > 0.0 ? theTol : BRep_Tool::Tolerance(theV);
495   B.UpdateVertex(aVertexCopy, theNewPos, aNewTol);
496
497   if (!isRecorded)
498     Replace(theV, aVertexCopy);
499
500   return aVertexCopy;
501 }
502
503 Standard_Boolean BRepTools_ReShape::IsNewShape(const TopoDS_Shape& theShape) const
504 {
505   return myNewShapes.Contains(theShape);
506 }
507
508 //=======================================================================
509 //function : History
510 //purpose  :
511 //=======================================================================
512
513 Handle(BRepTools_History) BRepTools_ReShape::History() const
514 {
515   Handle(BRepTools_History) aHistory = new BRepTools_History;
516
517   // Fill the history.
518   for (TShapeToReplacement::Iterator aRIt(myShapeToReplacement);
519     aRIt.More(); aRIt.Next())
520   {
521     const TopoDS_Shape& aShape = aRIt.Key();
522     if (!BRepTools_History::IsSupportedType(aShape) ||
523       myNewShapes.Contains(aShape))
524     {
525       continue;
526     }
527
528     NCollection_IndexedMap<TopoDS_Shape> aIntermediates;
529     NCollection_Map<TopoDS_Shape> aModified;
530     aIntermediates.Add(aShape);
531     for (Standard_Integer aI = 1; aI <= aIntermediates.Size(); ++aI)
532     {
533       const TopoDS_Shape& aIntermediate = aIntermediates(aI);
534       const TReplacement* aReplacement =
535         myShapeToReplacement.Seek(aIntermediate);
536       if (aReplacement == NULL)
537       {
538         Add(aModified, aIntermediate);
539       }
540       else if (aReplacement->RelationKind() !=
541         BRepTools_History::TRelationType_Removed)
542       {
543         const TopoDS_Shape aResult = aReplacement->RelationResult();
544         if (!aResult.IsNull())
545         {
546           Add(aIntermediates, aResult);
547         }
548       }
549     }
550
551     if (aModified.IsEmpty())
552     {
553       aHistory->Remove(aShape);
554     }
555     else
556     {
557       for (NCollection_Map<TopoDS_Shape>::Iterator aIt(aModified);
558         aIt.More(); aIt.Next())
559       {
560         aHistory->AddModified(aShape, aIt.Value());
561       }
562     }
563   }
564
565   return aHistory;
566 }