1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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
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 <Standard_Type.hxx>
27 #include <TopExp_Explorer.hxx>
28 #include <TopLoc_Location.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <TopoDS_Edge.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Iterator.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopoDS_Shell.hxx>
36 #include <TopoDS_Solid.hxx>
38 IMPLEMENT_STANDARD_RTTIEXT(BRepTools_ReShape,MMgt_TShared)
40 //include <ShapeExtend.hxx>
41 //#include <BRepTools_Edge.hxx>
42 static void CopyRanges (const TopoDS_Shape& toedge, const TopoDS_Shape& fromedge,
43 const Standard_Real alpha, const Standard_Real beta)
45 Handle(BRep_TEdge) aTEdgeFrom = Handle(BRep_TEdge)::DownCast(fromedge.TShape());
46 Handle(BRep_TEdge) aTEdgeTo = Handle(BRep_TEdge)::DownCast(toedge.TShape());
47 BRep_ListOfCurveRepresentation& tolist = aTEdgeTo->ChangeCurves();
48 BRep_ListIteratorOfListOfCurveRepresentation fromitcr (aTEdgeFrom->ChangeCurves());
49 for (; fromitcr.More(); fromitcr.Next()) {
50 Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
51 if ( fromGC.IsNull() ) continue;
52 Standard_Boolean isC3d = fromGC->IsCurve3D();
54 if(fromGC->Curve3D().IsNull()) continue; }
56 if(fromGC->PCurve().IsNull()) continue; }
58 if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated
60 Handle(Geom_Surface) surface;
63 surface = fromGC->Surface();
64 L = fromGC->Location();
67 Handle(BRep_GCurve) toGC;
68 for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) {
69 toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
70 if ( toGC.IsNull() ) continue;
72 if ( ! toGC->IsCurve3D() ) continue;
74 else if ( ! toGC->IsCurveOnSurface() ||
75 surface != toGC->Surface() || L != toGC->Location() ) continue;
76 Standard_Real first = fromGC->First();
77 Standard_Real last = fromGC->Last();
78 Standard_Real len = last - first;
79 toGC->SetRange ( first+alpha*len, first+beta*len );
86 //=======================================================================
87 //function : BRepTools_ReShape
89 //=======================================================================
91 BRepTools_ReShape::BRepTools_ReShape()
93 myConsiderLocation = Standard_False;
97 //=======================================================================
100 //=======================================================================
102 void BRepTools_ReShape::Clear()
109 //=======================================================================
112 //=======================================================================
114 void BRepTools_ReShape::Remove (const TopoDS_Shape& shape)
116 TopoDS_Shape nulshape;
117 Replace (shape,nulshape);
120 //=======================================================================
123 //=======================================================================
125 void BRepTools_ReShape::replace (const TopoDS_Shape& ashape,
126 const TopoDS_Shape& anewshape)
128 TopoDS_Shape shape = ashape;
129 TopoDS_Shape newshape = anewshape;
130 if ( shape.IsNull() || shape == newshape ) return;
132 if (shape.Orientation() == TopAbs_REVERSED)
137 // protect against INTERNAL or EXTERNAL shape
138 else if (shape.Orientation() == TopAbs_INTERNAL
139 || shape.Orientation() == TopAbs_EXTERNAL)
141 newshape.Orientation((newshape.Orientation() == shape.Orientation()) ?
142 TopAbs_FORWARD : TopAbs_REVERSED);
143 shape.Orientation(TopAbs_FORWARD);
146 if (myConsiderLocation) {
147 //sln 29.11.01 Bug22: Change location of 'newshape' in accordance with location of 'shape'
148 newshape.Location(newshape.Location().Multiplied(shape.Location().Inverted()));
149 TopLoc_Location nullLoc;
150 shape.Location ( nullLoc );
154 if ( IsRecorded ( shape ) && ((myConsiderLocation && ! Value ( shape ).IsPartner ( newshape )) ||
155 (!myConsiderLocation && ! Value ( shape ).IsSame ( newshape ))))
156 cout << "Warning: BRepTools_ReShape::Replace: shape already recorded" << endl;
159 myNMap.Bind (shape, newshape);
160 myNewShapes.Add (newshape);
164 //=======================================================================
165 //function : IsRecorded
167 //=======================================================================
169 Standard_Boolean BRepTools_ReShape::IsRecorded (const TopoDS_Shape& ashape) const
171 TopoDS_Shape shape = ashape;
172 if (myConsiderLocation) {
173 TopLoc_Location nullLoc;
174 shape.Location ( nullLoc );
176 if (shape.IsNull()) return Standard_False;
177 return myNMap.IsBound (shape);
181 //=======================================================================
184 //=======================================================================
186 TopoDS_Shape BRepTools_ReShape::Value (const TopoDS_Shape& ashape) const
189 if (ashape.IsNull()) return res;
190 TopoDS_Shape shape = ashape;
191 if (myConsiderLocation) {
192 TopLoc_Location nullLoc;
193 shape.Location ( nullLoc );
196 Standard_Boolean fromMap = Standard_False;
197 if ( shape.Orientation()==TopAbs_REVERSED ) {
198 if (!myNMap.IsBound (shape)) res = shape;
200 res = myNMap.Find (shape).Reversed();
201 fromMap = Standard_True;
205 if (!myNMap.IsBound (shape)) res = shape;
207 res = myNMap.Find (shape);
208 fromMap = Standard_True;
211 // for INTERNAL/EXTERNAL, since they are not fully supported, keep orientation
212 if ( shape.Orientation() == TopAbs_INTERNAL ||
213 shape.Orientation() == TopAbs_EXTERNAL )
214 res.Orientation ( shape.Orientation() );
216 if (myConsiderLocation) {
217 //sln 29.11.01 Bug22: Recalculate location of resulting shape in accordance with
218 //whether result is from map or not
219 if(fromMap) res.Location(ashape.Location()*res.Location());
220 else res.Location(ashape.Location());
227 //=======================================================================
230 //=======================================================================
232 Standard_Integer BRepTools_ReShape::Status(const TopoDS_Shape& ashape,
234 const Standard_Boolean last)
236 Standard_Integer res = 0;
237 if (ashape.IsNull()) { newsh.Nullify(); return res; }
239 TopoDS_Shape shape = ashape;
240 TopLoc_Location aLocSh = shape.Location();
241 if (myConsiderLocation) {
242 TopLoc_Location nullLoc;
243 shape.Location ( nullLoc );
246 if (!myNMap.IsBound (shape)) { newsh = shape; res = 0; }
247 else { newsh = myNMap.Find (shape); res = 1; }
249 if (newsh.IsNull()) res = -1;
250 else if (newsh.IsEqual (shape)) res = 0;
251 else if ( last && ((myConsiderLocation && ! newsh.IsPartner (shape)) ||
252 (!myConsiderLocation && ! newsh.IsSame (shape)))) {
253 //TopoDS_Shape newnewsh;
254 //Standard_Integer newres = Status (newsh, newnewsh, last);
256 //if (newres) res = newres;
257 // sln 29.11.01 Bug24: Correction iteration through maps. Way of iteration used early does not
258 // correspond to way of storing information in the maps.
259 newsh = Apply(shape, TopAbs_SHAPE);
260 if (newsh.IsNull()) res = -1;
261 if (newsh.IsEqual (shape)) res = 0;
264 if(myConsiderLocation && !newsh.IsNull())
266 TopLoc_Location aResLoc = (res >0 && !newsh.Location().IsIdentity() ?
267 aLocSh * newsh.Location() : aLocSh);
268 newsh.Location(aResLoc);
273 //=======================================================================
274 //function : EncodeStatus
276 //=======================================================================
277 static Standard_Integer EncodeStatus (const Standard_Integer status)
280 case 0 : return 0x0000; //ShapeExtend_OK
281 case 1: return 0x0001; //ShapeExtend_DONE1
282 case 2: return 0x0002; //....
283 case 3: return 0x0004;
284 case 4: return 0x0008;
285 case 5: return 0x0010;
286 case 6: return 0x0020;
287 case 7: return 0x0040;
288 case 8: return 0x0080; //....
289 case 9 : return 0x00ff; //ShapeExtend_DONE
290 case 10: return 0x0100; //ShapeExtend_FAIL1
291 case 11: return 0x0200; //...
292 case 12: return 0x0400;
293 case 13: return 0x0800;
294 case 14: return 0x1000;
295 case 15: return 0x2000;
296 case 16: return 0x4000;
297 case 17: return 0x8000; //....
298 case 18 : return 0xff00; //ShapeExtend_FAIL
304 //=======================================================================
307 //=======================================================================
309 TopoDS_Shape BRepTools_ReShape::Apply (const TopoDS_Shape& shape,
310 const TopAbs_ShapeEnum until)
312 myStatus = EncodeStatus(0); //ShapeExtend::EncodeStatus ( ShapeExtend_OK );
313 if ( shape.IsNull() ) return shape;
315 // apply direct replacement
316 TopoDS_Shape newsh = Value ( shape );
318 // if shape removed, return NULL
319 if ( newsh.IsNull() ) {
320 myStatus = EncodeStatus (2); //ShapeExtend_DONE2
324 // if shape replaced, apply modifications to the result recursively
325 if ( (myConsiderLocation && ! newsh.IsPartner (shape)) ||
326 (!myConsiderLocation &&! newsh.IsSame ( shape )) ) {
327 TopoDS_Shape res = Apply ( newsh, until );
328 myStatus |= EncodeStatus(1); //ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
332 TopAbs_ShapeEnum st = shape.ShapeType(); //, subt;
333 if ( st >= until ) return newsh; // critere d arret
334 if(st == TopAbs_VERTEX || st == TopAbs_SHAPE)
336 // define allowed types of components
337 //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing.
340 case TopAbs_COMPOUND: subt = TopAbs_SHAPE; break;
341 case TopAbs_COMPSOLID: subt = TopAbs_SOLID; break;
342 case TopAbs_SOLID: subt = TopAbs_SHELL; break;
343 case TopAbs_SHELL: subt = TopAbs_FACE; break;
344 case TopAbs_FACE: subt = TopAbs_WIRE; break;
345 case TopAbs_WIRE: subt = TopAbs_EDGE; break;
346 case TopAbs_EDGE: subt = TopAbs_VERTEX; break;
349 default: return shape;
354 TopoDS_Shape result = shape.EmptyCopied();
355 TopAbs_Orientation orien = shape.Orientation();
356 result.Orientation(TopAbs_FORWARD); // protect against INTERNAL or EXTERNAL shapes
357 Standard_Boolean modif = Standard_False;
358 Standard_Integer locStatus = myStatus;
360 // apply recorded modifications to subshapes
361 Standard_Boolean isEmpty = Standard_True;
362 for ( TopoDS_Iterator it(shape,Standard_False); it.More(); it.Next() ) {
363 TopoDS_Shape sh = it.Value();
364 newsh = Apply ( sh, until );
366 if ( myStatus & EncodeStatus(4)) //ShapeExtend::DecodeStatus ( myStatus, ShapeExtend_DONE4 ) )
367 locStatus |= EncodeStatus(4); //|= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
370 if ( newsh.IsNull() ) {
371 locStatus |= EncodeStatus(4); //ShapeExtend::EncodeStatus ( ShapeExtend_DONE4 );
375 isEmpty = Standard_False;
376 locStatus |= EncodeStatus(3);//ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
377 if ( st == TopAbs_COMPOUND || newsh.ShapeType() == sh.ShapeType()) { //fix for SAMTECH bug OCC322 about abcense internal vertices after sewing.
378 B.Add ( result, newsh );
381 Standard_Integer nitems = 0;
382 for ( TopoDS_Iterator subit(newsh); subit.More(); subit.Next(), nitems++ ) {
383 TopoDS_Shape subsh = subit.Value();
384 if ( subsh.ShapeType() == sh.ShapeType() ) B.Add ( result, subsh );//fix for SAMTECH bug OCC322 about abcense internal vertices after sewing.
385 else locStatus |= EncodeStatus(10);//ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
387 if ( ! nitems ) locStatus |= EncodeStatus(10);//ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
389 if ( ! modif ) return shape;
391 // For empty topological containers (any kind of shape except vertex, edge
392 // and face) we have to produce an empty result
393 if ( isEmpty && st != TopAbs_VERTEX && st != TopAbs_EDGE && st != TopAbs_FACE )
395 result = TopoDS_Shape();
399 // restore Range on edge broken by EmptyCopied()
400 if ( st == TopAbs_EDGE ) {
401 CopyRanges (result, shape, 0, 1);
403 else if (st == TopAbs_FACE) {
404 TopoDS_Face face = TopoDS::Face ( shape );
405 if( BRep_Tool::NaturalRestriction( face ) ) {
407 aB.NaturalRestriction( TopoDS::Face ( result ), Standard_True );
410 else if (st == TopAbs_WIRE || st == TopAbs_SHELL)
411 result.Closed (BRep_Tool::IsClosed (result));
413 result.Orientation(orien);
416 Replace ( shape, result );
417 myStatus = locStatus;
423 //=======================================================================
426 //=======================================================================
428 /*Standard_Boolean BRepTools_ReShape::Status (const ShapeExtend_Status status) const
430 return ShapeExtend::DecodeStatus ( myStatus, status );
433 //=======================================================================
434 //function : CopyVertex
436 //=======================================================================
438 TopoDS_Vertex BRepTools_ReShape::CopyVertex(const TopoDS_Vertex& theV,
439 const Standard_Real theTol)
441 return CopyVertex(theV, BRep_Tool::Pnt(theV), theTol);
444 //=======================================================================
445 //function : CopyVertex
447 //=======================================================================
449 TopoDS_Vertex BRepTools_ReShape::CopyVertex(const TopoDS_Vertex& theV,
450 const gp_Pnt& theNewPos,
451 const Standard_Real theTol)
453 TopoDS_Vertex aVertexCopy;
454 Standard_Boolean isRecorded = IsRecorded(theV);
455 aVertexCopy = isRecorded ? TopoDS::Vertex(Apply(theV)) : TopoDS::Vertex(theV.EmptyCopied());
458 Standard_Real aNewTol = theTol > 0.0 ? theTol : BRep_Tool::Tolerance(theV);
459 B.UpdateVertex(aVertexCopy, theNewPos, aNewTol);
462 Replace(theV, aVertexCopy);
467 Standard_Boolean BRepTools_ReShape::IsNewShape(const TopoDS_Shape& theShape) const
469 return myNewShapes.Contains(theShape);