| 1 | // Created on: 1995-02-22 |
| 2 | // Created by: Jacques GOUSSARD |
| 3 | // Copyright (c) 1995-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 | |
| 18 | #include <BRep_Builder.hxx> |
| 19 | #include <BRep_GCurve.hxx> |
| 20 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
| 21 | #include <BRep_TEdge.hxx> |
| 22 | #include <BRep_Tool.hxx> |
| 23 | #include <BRepAdaptor_Curve.hxx> |
| 24 | #include <BRepAdaptor_Curve2d.hxx> |
| 25 | #include <BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal.hxx> |
| 26 | #include <BRepFill_DataMapOfShapeSequenceOfReal.hxx> |
| 27 | #include <BRepLib.hxx> |
| 28 | #include <BRepLib_MakeVertex.hxx> |
| 29 | #include <BRepOffsetAPI_DraftAngle.hxx> |
| 30 | #include <BRepOffsetAPI_SequenceOfSequenceOfReal.hxx> |
| 31 | #include <BRepOffsetAPI_SequenceOfSequenceOfShape.hxx> |
| 32 | #include <BRepTools.hxx> |
| 33 | #include <BRepTools_Substitution.hxx> |
| 34 | #include <Draft_Modification.hxx> |
| 35 | #include <Geom2d_Curve.hxx> |
| 36 | #include <Geom_Surface.hxx> |
| 37 | #include <gp_Dir.hxx> |
| 38 | #include <gp_Pln.hxx> |
| 39 | #include <Precision.hxx> |
| 40 | #include <Standard_ConstructionError.hxx> |
| 41 | #include <Standard_NoSuchObject.hxx> |
| 42 | #include <Standard_NullObject.hxx> |
| 43 | #include <StdFail_NotDone.hxx> |
| 44 | #include <TColgp_SequenceOfPnt.hxx> |
| 45 | #include <TColStd_SequenceOfReal.hxx> |
| 46 | #include <TopExp.hxx> |
| 47 | #include <TopExp_Explorer.hxx> |
| 48 | #include <TopLoc_Location.hxx> |
| 49 | #include <TopoDS.hxx> |
| 50 | #include <TopoDS_Face.hxx> |
| 51 | #include <TopoDS_Iterator.hxx> |
| 52 | #include <TopoDS_Shape.hxx> |
| 53 | #include <TopoDS_Wire.hxx> |
| 54 | #include <TopTools_DataMapOfShapeSequenceOfShape.hxx> |
| 55 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
| 56 | #include <TopTools_SequenceOfShape.hxx> |
| 57 | |
| 58 | #include <Geom2dInt_GInter.hxx> |
| 59 | #include <IntRes2d_IntersectionPoint.hxx> |
| 60 | |
| 61 | //======================================================================= |
| 62 | //function : BRepOffsetAPI_DraftAngle |
| 63 | //purpose : |
| 64 | //======================================================================= |
| 65 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle () {} |
| 66 | |
| 67 | |
| 68 | //======================================================================= |
| 69 | //function : BRepOffsetAPI_DraftAngle |
| 70 | //purpose : |
| 71 | //======================================================================= |
| 72 | |
| 73 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle (const TopoDS_Shape& S) |
| 74 | { |
| 75 | myInitialShape = S; |
| 76 | myModification = new Draft_Modification(S); |
| 77 | } |
| 78 | |
| 79 | |
| 80 | //======================================================================= |
| 81 | //function : Clear |
| 82 | //purpose : |
| 83 | //======================================================================= |
| 84 | |
| 85 | void BRepOffsetAPI_DraftAngle::Clear () |
| 86 | { |
| 87 | if (!myModification.IsNull()) { |
| 88 | Handle(Draft_Modification)::DownCast (myModification)->Clear(); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | |
| 93 | //======================================================================= |
| 94 | //function : Init |
| 95 | //purpose : |
| 96 | //======================================================================= |
| 97 | |
| 98 | void BRepOffsetAPI_DraftAngle::Init (const TopoDS_Shape& S) |
| 99 | { |
| 100 | myInitialShape = S; |
| 101 | NotDone(); |
| 102 | if (!myModification.IsNull()) { |
| 103 | Handle(Draft_Modification)::DownCast (myModification)->Init(S); |
| 104 | } |
| 105 | else { |
| 106 | myModification = new Draft_Modification(S); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | |
| 111 | //======================================================================= |
| 112 | //function : Add |
| 113 | //purpose : |
| 114 | //======================================================================= |
| 115 | |
| 116 | void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F, |
| 117 | const gp_Dir& D, |
| 118 | const Standard_Real Angle, |
| 119 | const gp_Pln& Plane, |
| 120 | const Standard_Boolean Flag) |
| 121 | { |
| 122 | // POP-DPF : protection |
| 123 | if ( Abs(Angle) <= 1.e-04 ) |
| 124 | return; |
| 125 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 126 | Handle(Draft_Modification)::DownCast (myModification)->Add(F,D,Angle,Plane, Flag); |
| 127 | } |
| 128 | |
| 129 | |
| 130 | //======================================================================= |
| 131 | //function : AddDone |
| 132 | //purpose : |
| 133 | //======================================================================= |
| 134 | |
| 135 | Standard_Boolean BRepOffsetAPI_DraftAngle::AddDone () const |
| 136 | { |
| 137 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 138 | return Handle(Draft_Modification)::DownCast (myModification) |
| 139 | ->ProblematicShape().IsNull(); |
| 140 | } |
| 141 | |
| 142 | |
| 143 | //======================================================================= |
| 144 | //function : Remove |
| 145 | //purpose : |
| 146 | //======================================================================= |
| 147 | |
| 148 | void BRepOffsetAPI_DraftAngle::Remove(const TopoDS_Face& F) |
| 149 | { |
| 150 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 151 | Handle(Draft_Modification)::DownCast (myModification)->Remove(F); |
| 152 | } |
| 153 | |
| 154 | |
| 155 | //======================================================================= |
| 156 | //function : ProblematicShape |
| 157 | //purpose : |
| 158 | //======================================================================= |
| 159 | |
| 160 | const TopoDS_Shape& BRepOffsetAPI_DraftAngle::ProblematicShape () const |
| 161 | { |
| 162 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 163 | return Handle(Draft_Modification)::DownCast (myModification)->ProblematicShape(); |
| 164 | } |
| 165 | |
| 166 | |
| 167 | //======================================================================= |
| 168 | //function : ErrorStatus |
| 169 | //purpose : |
| 170 | //======================================================================= |
| 171 | |
| 172 | Draft_ErrorStatus BRepOffsetAPI_DraftAngle::Status () const |
| 173 | { |
| 174 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 175 | return Handle(Draft_Modification)::DownCast (myModification)->Error(); |
| 176 | } |
| 177 | |
| 178 | |
| 179 | //======================================================================= |
| 180 | //function : ConnectedFaces |
| 181 | //purpose : |
| 182 | //======================================================================= |
| 183 | |
| 184 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces |
| 185 | (const TopoDS_Face& F) const |
| 186 | { |
| 187 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 188 | return Handle(Draft_Modification)::DownCast (myModification)->ConnectedFaces(F); |
| 189 | } |
| 190 | |
| 191 | |
| 192 | //======================================================================= |
| 193 | //function : ModifiedFaces |
| 194 | //purpose : |
| 195 | //======================================================================= |
| 196 | |
| 197 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ModifiedFaces() const |
| 198 | { |
| 199 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 200 | return Handle(Draft_Modification)::DownCast (myModification)->ModifiedFaces(); |
| 201 | } |
| 202 | |
| 203 | //======================================================================= |
| 204 | //function : Generated |
| 205 | //purpose : |
| 206 | //======================================================================= |
| 207 | |
| 208 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Shape& S) |
| 209 | { |
| 210 | myGenerated.Clear(); |
| 211 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 212 | Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification); |
| 213 | |
| 214 | if (S.ShapeType() == TopAbs_FACE) { |
| 215 | Handle(Geom_Surface) Surf; |
| 216 | TopLoc_Location L; |
| 217 | Standard_Real Tol; |
| 218 | Standard_Boolean RW,RF; |
| 219 | if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
| 220 | if(myVtxToReplace.IsEmpty()) |
| 221 | { |
| 222 | myGenerated.Append(ModifiedShape (S)); |
| 223 | } |
| 224 | else |
| 225 | { |
| 226 | myGenerated.Append(mySubs.Value(ModifiedShape (S))); |
| 227 | } |
| 228 | } |
| 229 | } |
| 230 | return myGenerated; |
| 231 | } |
| 232 | |
| 233 | //======================================================================= |
| 234 | //function : Modified |
| 235 | //purpose : |
| 236 | //======================================================================= |
| 237 | |
| 238 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shape& S) |
| 239 | { |
| 240 | myGenerated.Clear(); |
| 241 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
| 242 | Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification); |
| 243 | |
| 244 | if (S.ShapeType() == TopAbs_FACE) { |
| 245 | Handle(Geom_Surface) Surf; |
| 246 | TopLoc_Location L; |
| 247 | Standard_Real Tol; |
| 248 | Standard_Boolean RW,RF; |
| 249 | |
| 250 | if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
| 251 | // Ce n est pas une generation => peut etre une modif |
| 252 | if(myVtxToReplace.IsEmpty()) |
| 253 | { |
| 254 | myGenerated.Append(ModifiedShape (S)); |
| 255 | } |
| 256 | else |
| 257 | { |
| 258 | myGenerated.Append(mySubs.Value(ModifiedShape (S))); |
| 259 | } |
| 260 | if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) { |
| 261 | myGenerated.Clear(); |
| 262 | } |
| 263 | } |
| 264 | } |
| 265 | return myGenerated; |
| 266 | } |
| 267 | |
| 268 | //======================================================================= |
| 269 | //function : ModifiedShape |
| 270 | //purpose : |
| 271 | //======================================================================= |
| 272 | |
| 273 | TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape |
| 274 | (const TopoDS_Shape& S) const |
| 275 | { |
| 276 | if(S.ShapeType() == TopAbs_VERTEX) |
| 277 | { |
| 278 | if(myVtxToReplace.IsBound(S)) |
| 279 | { |
| 280 | return myVtxToReplace(S); |
| 281 | } |
| 282 | } |
| 283 | if(myVtxToReplace.IsEmpty()) |
| 284 | { |
| 285 | return myModifier.ModifiedShape(S); |
| 286 | } |
| 287 | else |
| 288 | { |
| 289 | const TopoDS_Shape& aNS = myModifier.ModifiedShape(S); |
| 290 | return mySubs.Value(aNS); |
| 291 | } |
| 292 | } |
| 293 | |
| 294 | //======================================================================= |
| 295 | //function : Build |
| 296 | //purpose : |
| 297 | //======================================================================= |
| 298 | |
| 299 | void BRepOffsetAPI_DraftAngle::Build() |
| 300 | { |
| 301 | Handle(Draft_Modification)::DownCast (myModification)->Perform(); |
| 302 | if (!Handle(Draft_Modification)::DownCast (myModification)->IsDone()) { |
| 303 | NotDone(); |
| 304 | } |
| 305 | else { |
| 306 | DoModif(myInitialShape); |
| 307 | CorrectWires(); |
| 308 | CorrectVertexTol(); |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | //======================================================================= |
| 313 | //function : CorrectWires |
| 314 | //purpose : |
| 315 | //======================================================================= |
| 316 | |
| 317 | void BRepOffsetAPI_DraftAngle::CorrectWires() |
| 318 | { |
| 319 | Standard_Real TolInter = 1.e-7; |
| 320 | Standard_Integer i, j, k; |
| 321 | |
| 322 | TopTools_SequenceOfShape Eseq; |
| 323 | TopTools_SequenceOfShape Wseq; |
| 324 | TopTools_SequenceOfShape Fseq; |
| 325 | TopoDS_Shape CurEdge, CurWire, CurFace; |
| 326 | TopoDS_Iterator wit, eit; |
| 327 | |
| 328 | TopExp_Explorer fexp( myShape, TopAbs_FACE ); |
| 329 | for (; fexp.More(); fexp.Next()) |
| 330 | { |
| 331 | CurFace = fexp.Current(); |
| 332 | wit.Initialize( CurFace ); |
| 333 | for (; wit.More(); wit.Next()) |
| 334 | { |
| 335 | CurWire = wit.Value(); |
| 336 | TopTools_MapOfShape emap; |
| 337 | eit.Initialize( CurWire ); |
| 338 | for (; eit.More(); eit.Next()) |
| 339 | emap.Add( eit.Value() ); |
| 340 | TopTools_MapIteratorOfMapOfShape mapit( emap ); |
| 341 | for (; mapit.More(); mapit.Next()) |
| 342 | { |
| 343 | CurEdge = mapit.Key(); |
| 344 | if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) )) |
| 345 | { |
| 346 | Eseq.Append( CurEdge ); |
| 347 | Wseq.Append( CurWire ); |
| 348 | Fseq.Append( CurFace ); |
| 349 | } |
| 350 | } |
| 351 | } |
| 352 | } |
| 353 | |
| 354 | BRepFill_DataMapOfShapeSequenceOfReal Emap; |
| 355 | |
| 356 | TopTools_SequenceOfShape NonSeam; |
| 357 | TopTools_SequenceOfShape NonSeamWires; |
| 358 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsNonSeam; |
| 359 | BRepOffsetAPI_SequenceOfSequenceOfShape Seam; |
| 360 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsSeam; |
| 361 | |
| 362 | TopTools_DataMapOfShapeShape WFmap; |
| 363 | TopTools_DataMapOfShapeListOfShape WWmap; |
| 364 | for (i = 1; i <= Eseq.Length(); i++) |
| 365 | { |
| 366 | CurEdge = Eseq(i); |
| 367 | CurWire = Wseq(i); |
| 368 | CurFace = Fseq(i); |
| 369 | // |
| 370 | const TopoDS_Face& aFace = TopoDS::Face(CurFace); |
| 371 | // |
| 372 | // Prepare 2D adaptors for intersection. |
| 373 | // The seam edge has two 2D curve, thus we have to create 2 adaptors |
| 374 | BRepAdaptor_Curve2d aBAC2D1(TopoDS::Edge(CurEdge), aFace); |
| 375 | BRepAdaptor_Curve2d aBAC2D1R(TopoDS::Edge(CurEdge.Reversed()), aFace); |
| 376 | // Get surface of the face to get 3D intersection point |
| 377 | TopLoc_Location aLoc; |
| 378 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLoc); |
| 379 | // Get the tolerance of the current edge to compare intersection points |
| 380 | Standard_Real aTolCurE = BRep_Tool::Tolerance(TopoDS::Edge(CurEdge)); |
| 381 | // |
| 382 | wit.Initialize( CurFace ); |
| 383 | for (; wit.More(); wit.Next()) |
| 384 | { |
| 385 | TopoDS_Shape aWire = wit.Value(); |
| 386 | if (! aWire.IsSame( CurWire )) |
| 387 | { |
| 388 | TColgp_SequenceOfPnt pts; |
| 389 | Standard_Boolean Wadd = Standard_False; |
| 390 | eit.Initialize( aWire ); |
| 391 | for (; eit.More(); eit.Next()) |
| 392 | { |
| 393 | const TopoDS_Edge& anEdge = TopoDS::Edge(eit.Value()); |
| 394 | // |
| 395 | // Prepare 2D adaptor for intersection |
| 396 | BRepAdaptor_Curve2d aBAC2D2(anEdge, aFace); |
| 397 | // Perform intersection |
| 398 | Geom2dInt_GInter aGInter; |
| 399 | aGInter.Perform(aBAC2D1, aBAC2D2, TolInter, TolInter); |
| 400 | if (!aGInter.IsDone() || aGInter.IsEmpty()) { |
| 401 | // If first intersection is empty try intersection with reversed edge |
| 402 | aGInter.Perform(aBAC2D1R, aBAC2D2, TolInter, TolInter); |
| 403 | if (!aGInter.IsDone() || aGInter.IsEmpty()) { |
| 404 | continue; |
| 405 | } |
| 406 | } |
| 407 | // |
| 408 | Wadd = Standard_True; |
| 409 | if (! WFmap.IsBound( aWire )) |
| 410 | WFmap.Bind( aWire, CurFace ); |
| 411 | Standard_Integer ind = 0; |
| 412 | for (j = 1; j <= NonSeam.Length(); j++) { |
| 413 | if (anEdge.IsSame(NonSeam(j))) |
| 414 | { |
| 415 | ind = j; |
| 416 | break; |
| 417 | } |
| 418 | } |
| 419 | if (ind == 0) |
| 420 | { |
| 421 | NonSeam.Append(anEdge); |
| 422 | NonSeamWires.Append(aWire); |
| 423 | ind = NonSeam.Length(); |
| 424 | TColStd_SequenceOfReal emptyseq1, emptyseq2; |
| 425 | TopTools_SequenceOfShape emptyedgeseq; |
| 426 | ParsNonSeam.Append(emptyseq1); |
| 427 | Seam.Append(emptyedgeseq); |
| 428 | ParsSeam.Append(emptyseq2); |
| 429 | } |
| 430 | if (!Emap.IsBound(CurEdge)) |
| 431 | { |
| 432 | TColStd_SequenceOfReal emptyseq; |
| 433 | Emap.Bind(CurEdge, emptyseq); |
| 434 | } |
| 435 | // |
| 436 | // Get the tolerance of edge to compare intersection points |
| 437 | Standard_Real aTolE = BRep_Tool::Tolerance(anEdge); |
| 438 | // Tolerance to compare the intersection points is the maximal |
| 439 | // tolerance of intersecting edges |
| 440 | Standard_Real aTolCmp = Max(aTolCurE, aTolE); |
| 441 | // |
| 442 | Standard_Integer aNbIntPnt = aGInter.NbPoints(); |
| 443 | for (k = 1; k <= aNbIntPnt; ++k) { |
| 444 | const IntRes2d_IntersectionPoint& aP2DInt = aGInter.Point(k); |
| 445 | const gp_Pnt2d& aP2D = aP2DInt.Value(); |
| 446 | gp_Pnt aP3D = aSurf->Value(aP2D.X(), aP2D.Y()); |
| 447 | // |
| 448 | // Check if the intersection point is new |
| 449 | Standard_Integer ied = 0; |
| 450 | for (j = 1; j <= pts.Length(); j++) { |
| 451 | if (aP3D.IsEqual(pts(j), aTolCmp)) |
| 452 | { |
| 453 | ied = j; |
| 454 | break; |
| 455 | } |
| 456 | } |
| 457 | if (ied == 0) |
| 458 | { |
| 459 | pts.Append(aP3D); |
| 460 | Emap(CurEdge).Append(aP2DInt.ParamOnFirst()); |
| 461 | ParsNonSeam(ind).Append(aP2DInt.ParamOnSecond()); |
| 462 | Seam(ind).Append(CurEdge); |
| 463 | ParsSeam(ind).Append(aP2DInt.ParamOnFirst()); |
| 464 | } |
| 465 | } |
| 466 | } //for (; eit.More(); eit.Next()) |
| 467 | if (Wadd) |
| 468 | { |
| 469 | if (! WWmap.IsBound( CurWire )) |
| 470 | { |
| 471 | TopTools_ListOfShape emptylist; |
| 472 | WWmap.Bind( CurWire, emptylist ); |
| 473 | } |
| 474 | WWmap(CurWire).Append( aWire ); |
| 475 | } |
| 476 | } //if (! aWire.IsSame( CurWire )) |
| 477 | } //for (; wit.More(); wit.Next()) |
| 478 | } //for (i = 1; i <= Eseq.Length(); i++) |
| 479 | |
| 480 | //Sorting |
| 481 | for (i = 1; i <= NonSeam.Length(); i++) |
| 482 | for (j = 1; j < ParsNonSeam(i).Length(); j++) |
| 483 | for (k = j+1; k <= ParsNonSeam(i).Length(); k++) |
| 484 | if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j)) |
| 485 | { |
| 486 | Standard_Real temp = ParsNonSeam(i)(j); |
| 487 | ParsNonSeam(i)(j) = ParsNonSeam(i)(k); |
| 488 | ParsNonSeam(i)(k) = temp; |
| 489 | TopoDS_Shape tmp = Seam(i)(j); |
| 490 | Seam(i)(j) = Seam(i)(k); |
| 491 | Seam(i)(k) = tmp; |
| 492 | temp = ParsSeam(i)(j); |
| 493 | ParsSeam(i)(j) = ParsSeam(i)(k); |
| 494 | ParsSeam(i)(k) = temp; |
| 495 | } |
| 496 | BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap ); |
| 497 | for (; iter.More(); iter.Next()) |
| 498 | { |
| 499 | TColStd_SequenceOfReal Seq; |
| 500 | Seq = iter.Value(); |
| 501 | for (i = 1; i < Seq.Length(); i++) |
| 502 | for (j = i+1; j <= Seq.Length(); j++) |
| 503 | if (Seq(j) < Seq(i)) |
| 504 | { |
| 505 | Standard_Real temp = Seq(i); |
| 506 | Seq(i) = Seq(j); |
| 507 | Seq(j) = temp; |
| 508 | } |
| 509 | Emap( iter.Key() ) = Seq; |
| 510 | } |
| 511 | BRepFill_DataMapOfShapeSequenceOfReal EPmap; |
| 512 | TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam |
| 513 | TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it |
| 514 | iter.Initialize( Emap ); |
| 515 | for (; iter.More(); iter.Next()) |
| 516 | { |
| 517 | TColStd_SequenceOfReal parseq; |
| 518 | EPmap.Bind( iter.Key(), parseq ); |
| 519 | TopTools_SequenceOfShape shapeseq; |
| 520 | EVmap.Bind( iter.Key(), shapeseq ); |
| 521 | TopTools_SequenceOfShape shapeseq2; |
| 522 | EWmap.Bind( iter.Key(), shapeseq2 ); |
| 523 | } |
| 524 | |
| 525 | //Reconstruction of non-seam edges |
| 526 | BRepTools_Substitution aSub; |
| 527 | BRep_Builder BB; |
| 528 | for (i = 1; i <= NonSeam.Length(); i++) |
| 529 | { |
| 530 | TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) ); |
| 531 | TopTools_ListOfShape NewEdges; |
| 532 | TopoDS_Edge NewE; |
| 533 | TopoDS_Vertex Vfirst, Vlast; |
| 534 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
| 535 | Standard_Real par, FirstPar, LastPar; |
| 536 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
| 537 | Standard_Integer firstind = 1; |
| 538 | par = ParsNonSeam(i)(1); |
| 539 | TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) ); |
| 540 | //Find the face |
| 541 | for (j = 1; j <= Eseq.Length(); j++) |
| 542 | if (SeamEdge.IsSame( Eseq(j) )) |
| 543 | break; |
| 544 | TopoDS_Face theFace = TopoDS::Face( Fseq(j) ); |
| 545 | TopLoc_Location L; |
| 546 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L ); |
| 547 | if (Abs(par-FirstPar) <= Precision::Confusion()) |
| 548 | { |
| 549 | BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) ); |
| 550 | EPmap( SeamEdge ).Append( ParsSeam(i)(1) ); |
| 551 | EVmap( SeamEdge ).Append( Vfirst ); |
| 552 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
| 553 | firstind = 2; |
| 554 | } |
| 555 | Standard_Real prevpar = FirstPar; |
| 556 | TopoDS_Vertex PrevV = Vfirst; |
| 557 | for (j = firstind; j <= ParsNonSeam(i).Length(); j++) |
| 558 | { |
| 559 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
| 560 | NewE = TopoDS::Edge( aLocalShape ); |
| 561 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
| 562 | TopoDS_Vertex NewV; |
| 563 | par = ParsNonSeam(i)(j); |
| 564 | BB.Range( NewE, prevpar, par ); |
| 565 | SeamEdge = TopoDS::Edge( Seam(i)(j) ); |
| 566 | if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion()) |
| 567 | { |
| 568 | NewV = Vlast; |
| 569 | if (firstind == 2 && j == 2) |
| 570 | { |
| 571 | BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) ); |
| 572 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
| 573 | EVmap( SeamEdge ).Append( Vlast ); |
| 574 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
| 575 | break; |
| 576 | } |
| 577 | } |
| 578 | else |
| 579 | { |
| 580 | BRepAdaptor_Curve bcur( NewE ); |
| 581 | gp_Pnt Point = bcur.Value( par ); |
| 582 | NewV = BRepLib_MakeVertex( Point ); |
| 583 | BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() ); |
| 584 | } |
| 585 | BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() ); |
| 586 | NewE.Orientation( TopAbs_FORWARD ); |
| 587 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
| 588 | BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) ); |
| 589 | |
| 590 | NewEdges.Append( NewE ); |
| 591 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
| 592 | EVmap( SeamEdge ).Append( NewV ); |
| 593 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
| 594 | |
| 595 | prevpar = par; |
| 596 | PrevV = NewV; |
| 597 | } |
| 598 | //The last edge |
| 599 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
| 600 | NewE = TopoDS::Edge( aLocalShape ); |
| 601 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
| 602 | par = LastPar; |
| 603 | if (Abs(prevpar-par) > Precision::Confusion()) |
| 604 | { |
| 605 | BB.Range( NewE, prevpar, par ); |
| 606 | NewE.Orientation( TopAbs_FORWARD ); |
| 607 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
| 608 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
| 609 | NewEdges.Append( NewE ); |
| 610 | } |
| 611 | |
| 612 | //Substitute anEdge by NewEdges |
| 613 | aSub.Substitute( anEdge, NewEdges ); |
| 614 | } |
| 615 | |
| 616 | //Sorting of EPmap and EVmap and removing repeating points from them |
| 617 | iter.Initialize( EPmap ); |
| 618 | for (; iter.More(); iter.Next()) |
| 619 | { |
| 620 | TColStd_SequenceOfReal Seq; |
| 621 | Seq = iter.Value(); |
| 622 | TopTools_SequenceOfShape SeqShape; |
| 623 | SeqShape = EVmap( iter.Key() ); |
| 624 | TopTools_SequenceOfShape SeqShape2; |
| 625 | SeqShape2 = EWmap( iter.Key() ); |
| 626 | for (i = 1; i < Seq.Length(); i++) |
| 627 | for (j = i+1; j <= Seq.Length(); j++) |
| 628 | if (Seq(j) < Seq(i)) |
| 629 | { |
| 630 | Standard_Real temp = Seq(i); |
| 631 | Seq(i) = Seq(j); |
| 632 | Seq(j) = temp; |
| 633 | TopoDS_Shape tmp = SeqShape(i); |
| 634 | SeqShape(i) = SeqShape(j); |
| 635 | SeqShape(j) = tmp; |
| 636 | tmp = SeqShape2(i); |
| 637 | SeqShape2(i) = SeqShape2(j); |
| 638 | SeqShape2(j) = tmp; |
| 639 | } |
| 640 | EPmap( iter.Key() ) = Seq; |
| 641 | EVmap( iter.Key() ) = SeqShape; |
| 642 | EWmap( iter.Key() ) = SeqShape2; |
| 643 | } |
| 644 | iter.Initialize( EPmap ); |
| 645 | for (; iter.More(); iter.Next()) |
| 646 | { |
| 647 | TColStd_SequenceOfReal Seq; |
| 648 | Seq = iter.Value(); |
| 649 | TopTools_SequenceOfShape SeqShape; |
| 650 | SeqShape = EVmap( iter.Key() ); |
| 651 | TopTools_SequenceOfShape SeqShape2; |
| 652 | SeqShape2 = EWmap( iter.Key() ); |
| 653 | Standard_Boolean remove = Standard_True; |
| 654 | while (remove) |
| 655 | { |
| 656 | remove = Standard_False; |
| 657 | for (i = 1; i < Seq.Length(); i++) |
| 658 | if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion()) |
| 659 | { |
| 660 | Seq.Remove(i+1); |
| 661 | SeqShape.Remove(i+1); |
| 662 | SeqShape2.Remove(i+1); |
| 663 | remove = Standard_True; |
| 664 | } |
| 665 | } |
| 666 | EPmap( iter.Key() ) = Seq; |
| 667 | EVmap( iter.Key() ) = SeqShape; |
| 668 | EWmap( iter.Key() ) = SeqShape2; |
| 669 | } |
| 670 | |
| 671 | //Reconstruction of seam edges |
| 672 | TopTools_DataMapOfShapeShape VEmap; |
| 673 | iter.Initialize( Emap ); |
| 674 | for (; iter.More(); iter.Next()) |
| 675 | { |
| 676 | TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() ); |
| 677 | Standard_Boolean onepoint = Standard_False; |
| 678 | TopTools_ListOfShape NewEdges; |
| 679 | TColStd_SequenceOfReal Seq; |
| 680 | Seq = iter.Value(); |
| 681 | TColStd_SequenceOfReal Seq2; |
| 682 | Seq2 = EPmap( anEdge ); |
| 683 | TopTools_SequenceOfShape SeqVer; |
| 684 | SeqVer = EVmap( anEdge ); |
| 685 | TopTools_SequenceOfShape SeqWire; |
| 686 | SeqWire = EWmap( anEdge ); |
| 687 | TopoDS_Vertex Vfirst, Vlast; |
| 688 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
| 689 | Standard_Real fpar, lpar, FirstPar, LastPar; |
| 690 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
| 691 | fpar = FirstPar; |
| 692 | lpar = Seq(1); |
| 693 | TopoDS_Edge NewE; |
| 694 | Standard_Integer firstind = 1; |
| 695 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
| 696 | { |
| 697 | firstind = 2; |
| 698 | fpar = Seq(1); |
| 699 | lpar = Seq(2); |
| 700 | } |
| 701 | else |
| 702 | { |
| 703 | if (Seq.Length()%2 != 0) |
| 704 | { |
| 705 | VEmap.Bind( Vfirst, anEdge ); |
| 706 | firstind = 2; |
| 707 | fpar = Seq(1); |
| 708 | if (Seq.Length() > 2) |
| 709 | lpar = Seq(2); |
| 710 | else |
| 711 | onepoint = Standard_True; |
| 712 | } |
| 713 | } |
| 714 | if (!onepoint) |
| 715 | { |
| 716 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
| 717 | NewE = TopoDS::Edge( aLocalShape ); |
| 718 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
| 719 | BB.Range( NewE, fpar, lpar ); |
| 720 | NewE.Orientation( TopAbs_FORWARD ); |
| 721 | if (firstind == 1) |
| 722 | { |
| 723 | BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) ); |
| 724 | aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED); |
| 725 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
| 726 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) ); |
| 727 | } |
| 728 | else |
| 729 | { |
| 730 | aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD); |
| 731 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
| 732 | aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED); |
| 733 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
| 734 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) ); |
| 735 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) ); |
| 736 | } |
| 737 | NewEdges.Append( NewE ); |
| 738 | |
| 739 | firstind++; |
| 740 | for (i = firstind; i < Seq.Length(); i += 2) |
| 741 | { |
| 742 | aLocalShape = anEdge.EmptyCopied(); |
| 743 | NewE = TopoDS::Edge( aLocalShape ); |
| 744 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
| 745 | fpar = Seq(i); |
| 746 | lpar = Seq(i+1); |
| 747 | BB.Range( NewE, fpar, lpar ); |
| 748 | //Find vertices |
| 749 | for (j = 1; j <= Seq2.Length(); j++) |
| 750 | if (Abs(fpar-Seq2(j)) <= Precision::Confusion()) |
| 751 | break; |
| 752 | NewE.Orientation( TopAbs_FORWARD ); |
| 753 | TopoDS_Shape aLocalShapeCur = SeqVer(j).Oriented(TopAbs_FORWARD); |
| 754 | BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur) ); |
| 755 | aLocalShapeCur = SeqVer(j+1).Oriented(TopAbs_REVERSED); |
| 756 | BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur ) ); |
| 757 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) ); |
| 758 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) ); |
| 759 | NewEdges.Append( NewE ); |
| 760 | } |
| 761 | } |
| 762 | |
| 763 | i = Seq.Length(); |
| 764 | fpar = Seq(i); |
| 765 | lpar = LastPar; |
| 766 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
| 767 | continue; |
| 768 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
| 769 | NewE = TopoDS::Edge( aLocalShape ); |
| 770 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
| 771 | BB.Range( NewE, fpar, lpar ); |
| 772 | NewE.Orientation( TopAbs_FORWARD ); |
| 773 | aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD); |
| 774 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
| 775 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) ); |
| 776 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
| 777 | NewEdges.Append( NewE ); |
| 778 | |
| 779 | //Substitute anEdge by NewEdges |
| 780 | aSub.Substitute( anEdge, NewEdges ); |
| 781 | } |
| 782 | |
| 783 | //Removing edges connected with missing extremities of seam edges |
| 784 | TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap ); |
| 785 | for (; itve.More(); itve.Next()) |
| 786 | { |
| 787 | TopoDS_Shape V = itve.Key(); |
| 788 | TopoDS_Shape E = itve.Value(); |
| 789 | TopoDS_Shape W; |
| 790 | for (i = 1; i <= Eseq.Length(); i++) |
| 791 | if (E.IsSame( Eseq(i) )) |
| 792 | { |
| 793 | W = Wseq(i); |
| 794 | break; |
| 795 | } |
| 796 | TopoDS_Shape Etoremove; |
| 797 | eit.Initialize( W ); |
| 798 | for (; eit.More(); eit.Next()) |
| 799 | { |
| 800 | TopoDS_Edge CurE = TopoDS::Edge( eit.Value() ); |
| 801 | if (CurE.IsSame( E )) |
| 802 | continue; |
| 803 | TopoDS_Vertex Vfirst, Vlast; |
| 804 | TopExp::Vertices( CurE, Vfirst, Vlast ); |
| 805 | if (Vfirst.IsSame( V ) || Vlast.IsSame( V )) |
| 806 | { |
| 807 | Etoremove = CurE; |
| 808 | break; |
| 809 | } |
| 810 | } |
| 811 | if (! Etoremove.IsNull()) |
| 812 | { |
| 813 | W.Free( Standard_True ); |
| 814 | BB.Remove( W, Etoremove ); |
| 815 | } |
| 816 | } |
| 817 | |
| 818 | aSub.Build( myShape ); |
| 819 | if (aSub.IsCopied( myShape )) |
| 820 | { |
| 821 | const TopTools_ListOfShape& listSh = aSub.Copy( myShape ); |
| 822 | if (! listSh.IsEmpty()) |
| 823 | myShape = listSh.First(); |
| 824 | } |
| 825 | |
| 826 | //Reconstruction of wires |
| 827 | TopTools_ListOfShape theCopy; |
| 828 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap ); |
| 829 | for (; itww.More(); itww.Next()) |
| 830 | { |
| 831 | CurWire = itww.Key(); |
| 832 | theCopy = aSub.Copy( CurWire ); |
| 833 | CurWire = theCopy.First(); |
| 834 | CurWire.Free( Standard_True ); |
| 835 | TopTools_ListIteratorOfListOfShape itl( itww.Value() ); |
| 836 | for (; itl.More(); itl.Next()) |
| 837 | { |
| 838 | TopoDS_Shape aWire = itl.Value(); |
| 839 | CurFace = WFmap( aWire ); |
| 840 | theCopy = aSub.Copy( aWire ); |
| 841 | aWire = theCopy.First(); |
| 842 | //Adjusting period |
| 843 | TopLoc_Location L; |
| 844 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L ); |
| 845 | eit.Initialize( aWire ); |
| 846 | for (; eit.More(); eit.Next()) |
| 847 | { |
| 848 | TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() ); |
| 849 | gp_Pnt2d Pfirst, Plast, Pmid; |
| 850 | BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast ); |
| 851 | BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) ); |
| 852 | Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. ); |
| 853 | gp_Vec2d offset; |
| 854 | Standard_Boolean translate = Standard_False; |
| 855 | if (Pfirst.X()-2.*M_PI > Precision::Confusion() || |
| 856 | Plast.X()-2.*M_PI > Precision::Confusion() || |
| 857 | Pmid.X()-2.*M_PI > Precision::Confusion()) |
| 858 | { |
| 859 | offset.SetCoord( -2.*M_PI, 0 ); |
| 860 | translate = Standard_True; |
| 861 | } |
| 862 | if (Pfirst.X() < -Precision::Confusion() || |
| 863 | Plast.X() < -Precision::Confusion() || |
| 864 | Pmid.X() < -Precision::Confusion()) |
| 865 | { |
| 866 | offset.SetCoord( 2.*M_PI, 0 ); |
| 867 | translate = Standard_True; |
| 868 | } |
| 869 | if (translate) |
| 870 | { |
| 871 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape()); |
| 872 | BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() ); |
| 873 | Handle(BRep_GCurve) GC; |
| 874 | |
| 875 | for (; itcr.More(); itcr.Next()) |
| 876 | { |
| 877 | GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
| 878 | if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L )) |
| 879 | { |
| 880 | Handle(Geom2d_Curve) PC = GC->PCurve(); |
| 881 | PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) ); |
| 882 | GC->PCurve( PC ); |
| 883 | TE->ChangeCurves().Remove( itcr ); |
| 884 | TE->ChangeCurves().Append( GC ); |
| 885 | break; |
| 886 | } |
| 887 | } |
| 888 | } |
| 889 | } |
| 890 | /////////////////// |
| 891 | eit.Initialize( aWire, Standard_False ); |
| 892 | for (; eit.More(); eit.Next()) |
| 893 | { |
| 894 | TopoDS_Shape anEdge = eit.Value(); |
| 895 | BB.Add( CurWire, anEdge ); |
| 896 | } |
| 897 | if (aSub.IsCopied( CurFace )) |
| 898 | { |
| 899 | theCopy = aSub.Copy( CurFace ); |
| 900 | CurFace = theCopy.First(); |
| 901 | } |
| 902 | CurFace.Free( Standard_True ); |
| 903 | BB.Remove( CurFace, aWire ); |
| 904 | } |
| 905 | } |
| 906 | } |
| 907 | //======================================================================= |
| 908 | //function : CorrectVertexTol |
| 909 | //purpose : |
| 910 | //======================================================================= |
| 911 | |
| 912 | void BRepOffsetAPI_DraftAngle::CorrectVertexTol() |
| 913 | { |
| 914 | TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges; |
| 915 | TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE); |
| 916 | for(; anExp.More(); anExp.Next()) |
| 917 | { |
| 918 | anInitEdges.Add(anExp.Current()); |
| 919 | TopoDS_Iterator anIter(anExp.Current()); |
| 920 | for(; anIter.More(); anIter.Next()) |
| 921 | { |
| 922 | anInitVertices.Add(anIter.Value()); |
| 923 | } |
| 924 | } |
| 925 | // |
| 926 | |
| 927 | BRep_Builder aBB; |
| 928 | myVtxToReplace.Clear(); |
| 929 | anExp.Init(myShape, TopAbs_EDGE); |
| 930 | for(; anExp.More(); anExp.Next()) |
| 931 | { |
| 932 | const TopoDS_Shape& anE = anExp.Current(); |
| 933 | //Skip old (not modified) edges |
| 934 | if(anInitEdges.Contains(anE)) |
| 935 | continue; |
| 936 | // |
| 937 | //Skip processed edges |
| 938 | if(aNewEdges.Contains(anE)) |
| 939 | continue; |
| 940 | // |
| 941 | aNewEdges.Add(anE); |
| 942 | // |
| 943 | Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE)); |
| 944 | TopoDS_Iterator anIter(anE); |
| 945 | for(; anIter.More(); anIter.Next()) |
| 946 | { |
| 947 | const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value()); |
| 948 | if(anInitVertices.Contains(aVtx)) |
| 949 | { |
| 950 | if(myVtxToReplace.IsBound(aVtx)) |
| 951 | { |
| 952 | aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol)); |
| 953 | } |
| 954 | else |
| 955 | { |
| 956 | Standard_Real aVTol = BRep_Tool::Tolerance(aVtx); |
| 957 | if(aVTol < anETol) |
| 958 | { |
| 959 | TopoDS_Vertex aNewVtx; |
| 960 | gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx); |
| 961 | aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol)); |
| 962 | aNewVtx.Orientation(aVtx.Orientation()); |
| 963 | myVtxToReplace.Bind(aVtx, aNewVtx); |
| 964 | } |
| 965 | } |
| 966 | } |
| 967 | else |
| 968 | { |
| 969 | aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol)); |
| 970 | } |
| 971 | } |
| 972 | } |
| 973 | // |
| 974 | if(myVtxToReplace.IsEmpty()) |
| 975 | { |
| 976 | return; |
| 977 | } |
| 978 | // |
| 979 | mySubs.Clear(); |
| 980 | TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace); |
| 981 | for(; anIter.More(); anIter.Next()) |
| 982 | { |
| 983 | mySubs.Replace(anIter.Key(), anIter.Value()); |
| 984 | } |
| 985 | mySubs.Apply( myShape ); |
| 986 | myShape = mySubs.Value(myShape); |
| 987 | // |
| 988 | } |