| 1 | // File: BRepAlgo_OrthogonalProjection.cxx |
| 2 | // Created: Mon Oct 13 16:36:58 1997 |
| 3 | // Author: Roman BORISOV |
| 4 | // <rbv@velox.nnov.matra-dtv.fr> |
| 5 | |
| 6 | #include <BRepAlgo_NormalProjection.ixx> |
| 7 | #include <ProjLib_CompProjectedCurve.hxx> |
| 8 | #include <TopTools_HSequenceOfShape.hxx> |
| 9 | #include <TopExp_Explorer.hxx> |
| 10 | #include <TopAbs.hxx> |
| 11 | #include <BRepAdaptor_Curve.hxx> |
| 12 | #include <BRepAdaptor_HCurve.hxx> |
| 13 | #include <BRepAdaptor_Surface.hxx> |
| 14 | #include <BRepAdaptor_HSurface.hxx> |
| 15 | #include <ProjLib_HCompProjectedCurve.hxx> |
| 16 | #include <TopoDS_Edge.hxx> |
| 17 | #include <TopoDS_Shape.hxx> |
| 18 | #include <Approx_CurveOnSurface.hxx> |
| 19 | #include <TopoDS.hxx> |
| 20 | #include <BRep_Builder.hxx> |
| 21 | #include <BRepLib_MakeVertex.hxx> |
| 22 | #include <BRepLib_MakeWire.hxx> |
| 23 | #include <Geom2dAdaptor_HCurve.hxx> |
| 24 | #include <Geom2d_Curve.hxx> |
| 25 | #include <Geom_BSplineCurve.hxx> |
| 26 | #include <GeomAdaptor.hxx> |
| 27 | #include <BRepLib_MakeEdge.hxx> |
| 28 | #include <BRepAlgo_BooleanOperations.hxx> |
| 29 | #include <TopOpeBRepBuild_HBuilder.hxx> |
| 30 | #include <BRepTopAdaptor_FClass2d.hxx> |
| 31 | #include <Precision.hxx> |
| 32 | #include <BRepAlgo_SequenceOfSequenceOfInteger.hxx> |
| 33 | #include <TopExp.hxx> |
| 34 | #include <BRepTools.hxx> |
| 35 | #include <TColgp_Array1OfPnt2d.hxx> |
| 36 | #include <TColStd_Array1OfReal.hxx> |
| 37 | #include <TColStd_Array1OfInteger.hxx> |
| 38 | #include <Geom2d_TrimmedCurve.hxx> |
| 39 | #include <Geom2d_BSplineCurve.hxx> |
| 40 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
| 41 | |
| 42 | #ifdef __OCC_DEBUG_CHRONO |
| 43 | #include <OSD_Timer.hxx> |
| 44 | |
| 45 | OSD_Chronometer chr_total, chr_init, chr_approx, chr_booltool; |
| 46 | |
| 47 | Standard_Real t_total, t_init, t_approx, t_booltool; |
| 48 | Standard_IMPORT Standard_Real t_init_point, t_dicho_bound; |
| 49 | Standard_IMPORT Standard_Integer init_point_count, dicho_bound_count; |
| 50 | |
| 51 | void InitChron(OSD_Chronometer& ch) |
| 52 | { |
| 53 | ch.Reset(); |
| 54 | ch.Start(); |
| 55 | } |
| 56 | |
| 57 | void ResultChron( OSD_Chronometer & ch, Standard_Real & time) |
| 58 | { |
| 59 | Standard_Real tch ; |
| 60 | ch.Stop(); |
| 61 | ch.Show(tch); |
| 62 | time=time +tch; |
| 63 | } |
| 64 | |
| 65 | #endif |
| 66 | //======================================================================= |
| 67 | //function : BRepAlgo_NormalProjection |
| 68 | //purpose : |
| 69 | //======================================================================= |
| 70 | |
| 71 | BRepAlgo_NormalProjection::BRepAlgo_NormalProjection() |
| 72 | : myWith3d(Standard_True) |
| 73 | |
| 74 | { |
| 75 | BRep_Builder BB; |
| 76 | BB.MakeCompound(TopoDS::Compound(myToProj)); |
| 77 | myFaceBounds=Standard_True; |
| 78 | SetDefaultParams(); |
| 79 | myMaxDist = -1; |
| 80 | } |
| 81 | |
| 82 | //======================================================================= |
| 83 | //function : BRepAlgo_NormalProjection |
| 84 | //purpose : |
| 85 | //======================================================================= |
| 86 | |
| 87 | BRepAlgo_NormalProjection::BRepAlgo_NormalProjection(const TopoDS_Shape& S) |
| 88 | : myWith3d(Standard_True) |
| 89 | { |
| 90 | BRep_Builder BB; |
| 91 | BB.MakeCompound(TopoDS::Compound(myToProj)); |
| 92 | SetDefaultParams(); |
| 93 | myMaxDist = -1; |
| 94 | Init(S); |
| 95 | } |
| 96 | |
| 97 | //======================================================================= |
| 98 | //function : Init |
| 99 | //purpose : |
| 100 | //======================================================================= |
| 101 | |
| 102 | void BRepAlgo_NormalProjection::Init(const TopoDS_Shape& S) |
| 103 | { |
| 104 | myShape = S; |
| 105 | } |
| 106 | |
| 107 | //======================================================================= |
| 108 | //function : Add |
| 109 | //purpose : |
| 110 | //======================================================================= |
| 111 | |
| 112 | void BRepAlgo_NormalProjection::Add(const TopoDS_Shape& ToProj) |
| 113 | { |
| 114 | BRep_Builder BB; |
| 115 | BB.Add(myToProj, ToProj); |
| 116 | } |
| 117 | |
| 118 | //======================================================================= |
| 119 | //function : SetParams |
| 120 | //purpose : |
| 121 | //======================================================================= |
| 122 | |
| 123 | void BRepAlgo_NormalProjection::SetParams(const Standard_Real Tol3D, |
| 124 | const Standard_Real Tol2D, |
| 125 | const GeomAbs_Shape InternalContinuity, |
| 126 | const Standard_Integer MaxDegree, |
| 127 | const Standard_Integer MaxSeg) |
| 128 | { |
| 129 | myTol3d = Tol3D; |
| 130 | myTol2d = Tol2D; |
| 131 | myContinuity = InternalContinuity; |
| 132 | myMaxDegree = MaxDegree; |
| 133 | myMaxSeg = MaxSeg; |
| 134 | } |
| 135 | |
| 136 | //======================================================================= |
| 137 | //function : SetDefaultParams |
| 138 | //purpose : |
| 139 | //======================================================================= |
| 140 | |
| 141 | void BRepAlgo_NormalProjection::SetDefaultParams() |
| 142 | { |
| 143 | myTol3d = 1.e-4; |
| 144 | myTol2d = Pow(myTol3d, 2./3); |
| 145 | myContinuity = GeomAbs_C2; |
| 146 | myMaxDegree = 14; |
| 147 | myMaxSeg = 16; |
| 148 | } |
| 149 | |
| 150 | //======================================================================= |
| 151 | //function : SetLimits |
| 152 | //purpose : |
| 153 | //======================================================================= |
| 154 | |
| 155 | void BRepAlgo_NormalProjection::SetLimit(const Standard_Boolean FaceBounds) |
| 156 | { |
| 157 | myFaceBounds = FaceBounds; |
| 158 | } |
| 159 | |
| 160 | //======================================================================= |
| 161 | //function : SetMaxDistance |
| 162 | //purpose : |
| 163 | //======================================================================= |
| 164 | |
| 165 | void BRepAlgo_NormalProjection::SetMaxDistance(const Standard_Real MaxDist) |
| 166 | { |
| 167 | myMaxDist = MaxDist; |
| 168 | } |
| 169 | |
| 170 | //======================================================================= |
| 171 | //function : Compute3d |
| 172 | //purpose : |
| 173 | //======================================================================= |
| 174 | |
| 175 | void BRepAlgo_NormalProjection::Compute3d(const Standard_Boolean With3d) |
| 176 | { |
| 177 | myWith3d = With3d; |
| 178 | } |
| 179 | |
| 180 | //======================================================================= |
| 181 | //function : Build |
| 182 | //purpose : |
| 183 | //======================================================================= |
| 184 | |
| 185 | void BRepAlgo_NormalProjection::Build() |
| 186 | { |
| 187 | #ifdef __OCC_DEBUG_CHRONO |
| 188 | Standard_Integer init_count = 0, approx_count = 0, booltool_count = 0; |
| 189 | t_total = 0; |
| 190 | t_init = 0; |
| 191 | t_approx = 0; |
| 192 | t_booltool = 0; |
| 193 | |
| 194 | t_init_point = 0; |
| 195 | init_point_count = 0; |
| 196 | |
| 197 | t_dicho_bound = 0; |
| 198 | dicho_bound_count = 0; |
| 199 | |
| 200 | InitChron(chr_total); |
| 201 | #endif |
| 202 | myIsDone = Standard_False; |
| 203 | ProjLib_CompProjectedCurve Projector; |
| 204 | Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape(); |
| 205 | Handle(TopTools_HSequenceOfShape) Faces = new TopTools_HSequenceOfShape(); |
| 206 | TopTools_ListOfShape DescenList; |
| 207 | Standard_Integer NbEdges = 0, NbFaces = 0, i, j, k; |
| 208 | TopExp_Explorer ExpOfWire, ExpOfShape; |
| 209 | Standard_Real Udeb, Ufin; |
| 210 | TopoDS_Shape VertexRes; |
| 211 | Standard_Boolean Only3d, Only2d, Elementary; |
| 212 | |
| 213 | // for isoparametric cases |
| 214 | TColgp_Array1OfPnt2d Poles(1, 2); |
| 215 | TColStd_Array1OfReal Knots(1, 2); |
| 216 | TColStd_Array1OfInteger Mults(1,2); |
| 217 | Standard_Integer Deg; |
| 218 | Deg = 1; |
| 219 | Mults(1) = Deg + 1; |
| 220 | Mults(2) = Deg + 1; |
| 221 | // |
| 222 | |
| 223 | for(ExpOfWire.Init(myToProj, TopAbs_EDGE); |
| 224 | ExpOfWire.More(); |
| 225 | ExpOfWire.Next(), NbEdges++) { |
| 226 | Edges->Append(ExpOfWire.Current()); |
| 227 | } |
| 228 | |
| 229 | for(ExpOfShape.Init(myShape, TopAbs_FACE); |
| 230 | ExpOfShape.More(); |
| 231 | ExpOfShape.Next(), NbFaces++) { |
| 232 | Faces->Append(ExpOfShape.Current()); |
| 233 | } |
| 234 | |
| 235 | BRep_Builder BB; |
| 236 | BB.MakeCompound(TopoDS::Compound(myRes)); |
| 237 | BB.MakeCompound(TopoDS::Compound(VertexRes)); |
| 238 | Standard_Boolean YaVertexRes = Standard_False; |
| 239 | |
| 240 | for(i = 1; i <= NbEdges; i++){ |
| 241 | DescenList.Clear(); |
| 242 | BRepAdaptor_Curve cur(TopoDS::Edge(Edges->Value(i))); |
| 243 | Handle(BRepAdaptor_HCurve) hcur = new BRepAdaptor_HCurve(); |
| 244 | hcur->Set(cur); |
| 245 | Elementary = IsElementary(cur); |
| 246 | for(j = 1; j <= NbFaces; j++){ |
| 247 | BRepAdaptor_Surface sur(TopoDS::Face(Faces->Value(j))); |
| 248 | Handle(BRepAdaptor_HSurface) hsur = new BRepAdaptor_HSurface(); |
| 249 | hsur->Set(sur); |
| 250 | |
| 251 | // computation of TolU and TolV |
| 252 | |
| 253 | Standard_Real TolU, TolV; |
| 254 | |
| 255 | TolU = hsur->UResolution(myTol3d)/20; |
| 256 | TolV = hsur->VResolution(myTol3d)/20; |
| 257 | // Projection |
| 258 | #ifdef __OCC_DEBUG_CHRONO |
| 259 | InitChron(chr_init); |
| 260 | #endif |
| 261 | Projector = |
| 262 | ProjLib_CompProjectedCurve(hsur, hcur, TolU, TolV, myMaxDist); |
| 263 | #ifdef __OCC_DEBUG_CHRONO |
| 264 | ResultChron(chr_init,t_init); |
| 265 | init_count++; |
| 266 | #endif |
| 267 | // |
| 268 | Handle(ProjLib_HCompProjectedCurve) HProjector = |
| 269 | new ProjLib_HCompProjectedCurve(); |
| 270 | HProjector->Set(Projector); |
| 271 | TopoDS_Shape prj; |
| 272 | Standard_Boolean Degenerated = Standard_False; |
| 273 | gp_Pnt2d P2d, Pdeb, Pfin; |
| 274 | gp_Pnt P; |
| 275 | Standard_Real UIso, VIso; |
| 276 | |
| 277 | Handle(Adaptor2d_HCurve2d) HPCur; |
| 278 | Handle(Geom2d_Curve) PCur2d; // Only for isoparametric projection |
| 279 | |
| 280 | for(k = 1; k <= Projector.NbCurves(); k++){ |
| 281 | if(Projector.IsSinglePnt(k, P2d)){ |
| 282 | #ifdef DEBUG |
| 283 | cout << "Projection of edge "<<i<<" on face "<<j; |
| 284 | cout << " is punctual"<<endl<<endl; |
| 285 | #endif |
| 286 | Projector.GetSurface()->D0(P2d.X(), P2d.Y(), P); |
| 287 | prj = BRepLib_MakeVertex(P).Shape(); |
| 288 | DescenList.Append(prj); |
| 289 | BB.Add(VertexRes, prj); |
| 290 | YaVertexRes = Standard_True; |
| 291 | |
| 292 | myAncestorMap.Bind(prj, Edges->Value(i)); |
| 293 | } |
| 294 | else { |
| 295 | Only2d = Only3d = Standard_False; |
| 296 | Projector.Bounds(k, Udeb, Ufin); |
| 297 | |
| 298 | /**************************************************************/ |
| 299 | if (Projector.IsUIso(k, UIso)) { |
| 300 | #ifdef DEBUG |
| 301 | cout << "Projection of edge "<<i<<" on face "<<j; |
| 302 | cout << " is U-isoparametric"<<endl<<endl; |
| 303 | #endif |
| 304 | Projector.D0(Udeb, Pdeb); |
| 305 | Projector.D0(Ufin, Pfin); |
| 306 | Poles(1) = Pdeb; |
| 307 | Poles(2) = Pfin; |
| 308 | Knots(1) = Udeb; |
| 309 | Knots(2) = Ufin; |
| 310 | Handle(Geom2d_BSplineCurve) BS2d = |
| 311 | new Geom2d_BSplineCurve(Poles, Knots, Mults, Deg); |
| 312 | PCur2d = new Geom2d_TrimmedCurve( BS2d, Udeb, Ufin); |
| 313 | HPCur = new Geom2dAdaptor_HCurve(PCur2d); |
| 314 | Only3d = Standard_True; |
| 315 | } |
| 316 | else if (Projector.IsVIso(k, VIso)) { |
| 317 | #ifdef DEBUG |
| 318 | cout << "Projection of edge "<<i<<" on face "<<j; |
| 319 | cout << " is V-isoparametric"<<endl<<endl; |
| 320 | #endif |
| 321 | Projector.D0(Udeb, Pdeb); |
| 322 | Projector.D0(Ufin, Pfin); |
| 323 | Poles(1) = Pdeb; |
| 324 | Poles(2) = Pfin; |
| 325 | Knots(1) = Udeb; |
| 326 | Knots(2) = Ufin; |
| 327 | Handle(Geom2d_BSplineCurve) BS2d = |
| 328 | new Geom2d_BSplineCurve(Poles, Knots, Mults, Deg); |
| 329 | PCur2d = new Geom2d_TrimmedCurve(BS2d, Udeb, Ufin); |
| 330 | HPCur = new Geom2dAdaptor_HCurve(PCur2d); |
| 331 | Only3d = Standard_True; |
| 332 | } |
| 333 | else HPCur = HProjector; |
| 334 | |
| 335 | if((myWith3d == Standard_False || Elementary) && |
| 336 | (Projector.MaxDistance(k) <= myTol3d) ) |
| 337 | Only2d = Standard_True; |
| 338 | |
| 339 | if(Only2d && Only3d) { |
| 340 | BRepLib_MakeEdge MKed(GeomAdaptor::MakeCurve(hcur->Curve()), |
| 341 | Ufin, Udeb); |
| 342 | prj = MKed.Edge(); |
| 343 | BB.UpdateEdge(TopoDS::Edge(prj), |
| 344 | PCur2d, |
| 345 | TopoDS::Face(Faces->Value(j)), |
| 346 | myTol3d); |
| 347 | BB.UpdateVertex(TopExp::FirstVertex(TopoDS::Edge(prj)),myTol3d); |
| 348 | BB.UpdateVertex(TopExp::LastVertex(TopoDS::Edge(prj)),myTol3d); |
| 349 | } |
| 350 | else { |
| 351 | #ifdef __OCC_DEBUG_CHRONO |
| 352 | InitChron(chr_approx); |
| 353 | #endif |
| 354 | Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d, |
| 355 | myContinuity, myMaxDegree, myMaxSeg, |
| 356 | Only3d, Only2d); |
| 357 | #ifdef __OCC_DEBUG_CHRONO |
| 358 | ResultChron(chr_approx,t_approx); |
| 359 | approx_count++; |
| 360 | |
| 361 | cout<<"Approximation.IsDone = "<<appr.IsDone()<<endl; |
| 362 | if(!Only2d) |
| 363 | cout<<"MaxError3d = "<<appr.MaxError3d()<<endl<<endl; |
| 364 | if(!Only3d) { |
| 365 | cout<<"MaxError2dU = "<<appr.MaxError2dU()<<endl; |
| 366 | cout<<"MaxError2dV = "<<appr.MaxError2dV()<<endl<<endl; |
| 367 | } |
| 368 | #endif |
| 369 | |
| 370 | |
| 371 | if(!Only3d) PCur2d = appr.Curve2d(); |
| 372 | if(Only2d) { |
| 373 | BRepLib_MakeEdge MKed(GeomAdaptor::MakeCurve(hcur->Curve()), |
| 374 | Udeb, Ufin); |
| 375 | prj = MKed.Edge(); |
| 376 | } |
| 377 | else { |
| 378 | // It is tested if the solution is not degenerated to set the |
| 379 | // flag on edge, one takes several points, checks if the cloud of |
| 380 | // points has less diameter than the tolerance 3D |
| 381 | Degenerated = Standard_True; |
| 382 | Standard_Real Dist; |
| 383 | Handle(Geom_BSplineCurve) BS3d = Handle(Geom_BSplineCurve)::DownCast( appr.Curve3d()); |
| 384 | gp_Pnt P1(0.,0.,0.),PP; // skl : I change "P" to "PP" |
| 385 | Standard_Integer NbPoint,ii ; // skl : I change "i" to "ii" |
| 386 | Standard_Real Par,DPar; |
| 387 | // start from 3 points to reject non degenerated edges |
| 388 | // very fast |
| 389 | NbPoint =3; |
| 390 | DPar = (BS3d->LastParameter()-BS3d->FirstParameter())/(NbPoint-1); |
| 391 | for (ii=0;ii<NbPoint;ii++) |
| 392 | { |
| 393 | Par=BS3d->FirstParameter()+ii*DPar; |
| 394 | PP=BS3d->Value(Par); |
| 395 | P1.SetXYZ(P1.XYZ() + PP.XYZ()/NbPoint); |
| 396 | } |
| 397 | for (ii=0;ii<NbPoint && Degenerated ;ii++) |
| 398 | { |
| 399 | Par=BS3d->FirstParameter()+ii*DPar; |
| 400 | PP=BS3d->Value(Par); |
| 401 | Dist=P1.Distance(PP); |
| 402 | if(Dist > myTol3d) { |
| 403 | Degenerated = Standard_False; |
| 404 | break; |
| 405 | } |
| 406 | } |
| 407 | // if the test passes a more exact test with 10 points |
| 408 | if (Degenerated) { |
| 409 | P1.SetCoord(0.,0.,0.); |
| 410 | NbPoint =10; |
| 411 | DPar = (BS3d->LastParameter()-BS3d->FirstParameter())/(NbPoint-1); |
| 412 | for (ii=0;ii<NbPoint;ii++) |
| 413 | { |
| 414 | Par=BS3d->FirstParameter()+ii*DPar; |
| 415 | PP=BS3d->Value(Par); |
| 416 | P1.SetXYZ(P1.XYZ() + PP.XYZ()/NbPoint); |
| 417 | } |
| 418 | for (ii=0;ii<NbPoint && Degenerated ;ii++) |
| 419 | { |
| 420 | Par=BS3d->FirstParameter()+ii*DPar; |
| 421 | PP=BS3d->Value(Par); |
| 422 | Dist=P1.Distance(PP); |
| 423 | if(Dist > myTol3d) { |
| 424 | Degenerated = Standard_False; |
| 425 | break; |
| 426 | } |
| 427 | } |
| 428 | } |
| 429 | if (Degenerated) { |
| 430 | #ifdef DEBUG |
| 431 | cout << "Projection of edge "<<i<<" on face "<<j; |
| 432 | cout << " is degenerated "<<endl<<endl; |
| 433 | #endif |
| 434 | TopoDS_Vertex VV; |
| 435 | BB.MakeVertex(VV); |
| 436 | BB.UpdateVertex(VV,P1,myTol3d); |
| 437 | BB.MakeEdge(TopoDS::Edge(prj)); |
| 438 | BB.Add(TopoDS::Edge(prj),VV.Oriented(TopAbs_FORWARD)); |
| 439 | BB.Add(TopoDS::Edge(prj),VV.Oriented(TopAbs_REVERSED)); |
| 440 | BB.Degenerated(TopoDS::Edge(prj), Standard_True); |
| 441 | } |
| 442 | else { |
| 443 | prj = BRepLib_MakeEdge(BS3d).Edge(); |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | BB.UpdateEdge(TopoDS::Edge(prj), |
| 448 | PCur2d, |
| 449 | TopoDS::Face(Faces->Value(j)), |
| 450 | appr.MaxError3d()); |
| 451 | BB.UpdateVertex(TopExp::FirstVertex(TopoDS::Edge(prj)),appr.MaxError3d()); |
| 452 | BB.UpdateVertex(TopExp::LastVertex(TopoDS::Edge(prj)),appr.MaxError3d()); |
| 453 | if (Degenerated) { |
| 454 | BB.Range(TopoDS::Edge(prj), |
| 455 | TopoDS::Face(Faces->Value(j)), |
| 456 | Udeb,Ufin); |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | if(myFaceBounds) { |
| 461 | // Trimming edges by face bounds |
| 462 | // if the solution is degenerated, use of BoolTool is avoided |
| 463 | #ifdef __OCC_DEBUG_CHRONO |
| 464 | InitChron(chr_booltool); |
| 465 | #endif |
| 466 | if(!Degenerated){ |
| 467 | BRepAlgo_BooleanOperations BoolTool; |
| 468 | BoolTool.Shapes2d(Faces->Value(j),prj); |
| 469 | BoolTool.Common(); |
| 470 | Handle(TopOpeBRepBuild_HBuilder) HB; |
| 471 | TopTools_ListOfShape LS; |
| 472 | TopTools_ListIteratorOfListOfShape Iter; |
| 473 | HB = BoolTool.Builder(); |
| 474 | LS.Clear(); |
| 475 | if (HB->IsSplit(prj, TopAbs_IN)) |
| 476 | LS = HB->Splits(prj, TopAbs_IN); |
| 477 | Iter.Initialize(LS); |
| 478 | if(Iter.More()) { |
| 479 | #ifdef DEBUG |
| 480 | cout << " BooleanOperations :" << Iter.More()<<" solutions " << endl; |
| 481 | #endif |
| 482 | for(; Iter.More(); Iter.Next()) { |
| 483 | BB.Add(myRes, Iter.Value()); |
| 484 | myAncestorMap.Bind(Iter.Value(), Edges->Value(i)); |
| 485 | myCorresp.Bind(Iter.Value(),Faces->Value(j)); |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | else { |
| 490 | |
| 491 | BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)), |
| 492 | Precision::Confusion()); |
| 493 | gp_Pnt2d Puv; |
| 494 | Standard_Real f = PCur2d->FirstParameter(); |
| 495 | Standard_Real l = PCur2d->LastParameter(); |
| 496 | Standard_Real pmil = (f + l )/2; |
| 497 | PCur2d->D0(pmil, Puv); |
| 498 | TopAbs_State state; |
| 499 | state = classifier.Perform(Puv); |
| 500 | if(state == TopAbs_IN || state == TopAbs_ON) { |
| 501 | BB.Add(myRes, prj); |
| 502 | DescenList.Append(prj); |
| 503 | myAncestorMap.Bind(prj, Edges->Value(i)); |
| 504 | myCorresp.Bind(prj, Faces->Value(j)); |
| 505 | } |
| 506 | } |
| 507 | } |
| 508 | else { |
| 509 | #ifdef DEB |
| 510 | cout << " BooleanOperations : no solution " << endl; |
| 511 | #endif |
| 512 | |
| 513 | BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)), |
| 514 | Precision::Confusion()); |
| 515 | gp_Pnt2d Puv; |
| 516 | Standard_Real f = PCur2d->FirstParameter(); |
| 517 | Standard_Real l = PCur2d->LastParameter(); |
| 518 | Standard_Real pmil = (f + l )/2; |
| 519 | PCur2d->D0(pmil, Puv); |
| 520 | TopAbs_State state; |
| 521 | state = classifier.Perform(Puv); |
| 522 | if(state == TopAbs_IN || state == TopAbs_ON) { |
| 523 | BB.Add(myRes, prj); |
| 524 | DescenList.Append(prj); |
| 525 | myAncestorMap.Bind(prj, Edges->Value(i)); |
| 526 | myCorresp.Bind(prj, Faces->Value(j)); |
| 527 | } |
| 528 | #ifdef __OCC_DEBUG_CHRONO |
| 529 | ResultChron(chr_booltool,t_booltool); |
| 530 | booltool_count++; |
| 531 | #endif |
| 532 | } |
| 533 | } |
| 534 | else { |
| 535 | BB.Add(myRes, prj); |
| 536 | DescenList.Append(prj); |
| 537 | myAncestorMap.Bind(prj, Edges->Value(i)); |
| 538 | myCorresp.Bind(prj, Faces->Value(j)); |
| 539 | } |
| 540 | } |
| 541 | } |
| 542 | } |
| 543 | myDescendants.Bind(Edges->Value(i), DescenList); |
| 544 | } |
| 545 | // JPI : eventual wire creation is reported in a specific method |
| 546 | // BuilWire that can be called by the user. Otherwise, the |
| 547 | // relations of map myAncestorMap, myCorresp will be lost. |
| 548 | |
| 549 | if(YaVertexRes) BB.Add(myRes, VertexRes); |
| 550 | |
| 551 | myIsDone = Standard_True; |
| 552 | |
| 553 | #ifdef __OCC_DEBUG_CHRONO |
| 554 | ResultChron(chr_total,t_total); |
| 555 | |
| 556 | cout<<"Build - Total time : "<<t_total<<" includes:" <<endl; |
| 557 | cout<<"- Projection : "<<t_init<<endl; |
| 558 | cout<<" -- Initial point search : "<<t_init_point<<endl; |
| 559 | cout<<" -- DichoBound search : "<<t_dicho_bound<<endl; |
| 560 | cout<<"- Approximation : "<<t_approx<<endl; |
| 561 | cout<<"- Boolean operation : "<<t_booltool<<endl; |
| 562 | cout<<"- Rest of time : "<<t_total-(t_init + t_approx + t_booltool )<<endl<<endl; |
| 563 | if (init_count != 0) |
| 564 | t_init /= init_count; |
| 565 | if (init_point_count != 0) |
| 566 | t_init_point /= init_point_count; |
| 567 | if (dicho_bound_count != 0) |
| 568 | t_dicho_bound /= dicho_bound_count; |
| 569 | if (approx_count != 0) |
| 570 | t_approx /= approx_count; |
| 571 | if (booltool_count != 0) |
| 572 | t_booltool /= booltool_count; |
| 573 | |
| 574 | cout<<"Unitary average time : "<<endl; |
| 575 | cout<<"- Projection : "<<t_init<<endl; |
| 576 | cout<<" -- Initial point search: "<<t_init_point<<endl; |
| 577 | cout<<" -- DichoBound search : "<<t_dicho_bound<<endl; |
| 578 | cout<<"- Approximation : "<<t_approx<<endl; |
| 579 | cout<<"- Boolean operation :"<<t_booltool<<endl; |
| 580 | cout<<endl<<"Number of initial point computations is "<<init_point_count<<endl<<endl; |
| 581 | #endif |
| 582 | } |
| 583 | |
| 584 | //======================================================================= |
| 585 | //function : IsDone |
| 586 | //purpose : |
| 587 | //======================================================================= |
| 588 | |
| 589 | Standard_Boolean BRepAlgo_NormalProjection::IsDone() const |
| 590 | { |
| 591 | return myIsDone; |
| 592 | } |
| 593 | |
| 594 | //======================================================================= |
| 595 | //function : Projection |
| 596 | //purpose : |
| 597 | //======================================================================= |
| 598 | |
| 599 | const TopoDS_Shape& BRepAlgo_NormalProjection::Projection() const |
| 600 | { |
| 601 | return myRes; |
| 602 | } |
| 603 | |
| 604 | //======================================================================= |
| 605 | //function : Ancestor |
| 606 | //purpose : |
| 607 | //======================================================================= |
| 608 | |
| 609 | const TopoDS_Shape& BRepAlgo_NormalProjection::Ancestor(const TopoDS_Edge& E) const |
| 610 | { |
| 611 | return myAncestorMap.Find(E); |
| 612 | } |
| 613 | |
| 614 | //======================================================================= |
| 615 | //function : Couple |
| 616 | //purpose : |
| 617 | //======================================================================= |
| 618 | |
| 619 | const TopoDS_Shape& BRepAlgo_NormalProjection::Couple(const TopoDS_Edge& E) const |
| 620 | { |
| 621 | return myCorresp.Find(E); |
| 622 | } |
| 623 | |
| 624 | //======================================================================= |
| 625 | //function : Generated |
| 626 | //purpose : |
| 627 | //======================================================================= |
| 628 | |
| 629 | const TopTools_ListOfShape& BRepAlgo_NormalProjection::Generated(const TopoDS_Shape& S) |
| 630 | { |
| 631 | return myDescendants.Find(S); |
| 632 | } |
| 633 | |
| 634 | //======================================================================= |
| 635 | //function : IsElementary |
| 636 | //purpose : |
| 637 | //======================================================================= |
| 638 | |
| 639 | Standard_Boolean BRepAlgo_NormalProjection::IsElementary(const Adaptor3d_Curve& C) const |
| 640 | { |
| 641 | GeomAbs_CurveType type; |
| 642 | type = C.GetType(); |
| 643 | switch(type) { |
| 644 | case GeomAbs_Line: |
| 645 | case GeomAbs_Circle: |
| 646 | case GeomAbs_Ellipse: |
| 647 | case GeomAbs_Hyperbola: |
| 648 | case GeomAbs_Parabola: return Standard_True; |
| 649 | default: return Standard_False; |
| 650 | } |
| 651 | } |
| 652 | //======================================================================= |
| 653 | //function : BuildWire |
| 654 | //purpose : |
| 655 | //======================================================================= |
| 656 | |
| 657 | Standard_Boolean BRepAlgo_NormalProjection::BuildWire(TopTools_ListOfShape& ListOfWire) const |
| 658 | { |
| 659 | TopExp_Explorer ExpOfWire, ExpOfShape; |
| 660 | Standard_Boolean IsWire=Standard_False; |
| 661 | ExpOfShape.Init(myRes, TopAbs_EDGE); |
| 662 | if(ExpOfShape.More()) |
| 663 | { |
| 664 | TopTools_ListOfShape List; |
| 665 | |
| 666 | for ( ; ExpOfShape.More(); ExpOfShape.Next()) |
| 667 | { |
| 668 | const TopoDS_Shape& CurE = ExpOfShape.Current(); |
| 669 | List.Append(CurE); |
| 670 | } |
| 671 | BRepLib_MakeWire MW; |
| 672 | MW.Add(List); |
| 673 | if (MW.IsDone()) |
| 674 | { |
| 675 | const TopoDS_Shape& Wire = MW.Shape(); |
| 676 | // If the resulting wire contains the same edge as at the beginning OK |
| 677 | // otherwise the result really consists of several wires. |
| 678 | TopExp_Explorer exp2(Wire,TopAbs_EDGE); |
| 679 | Standard_Integer NbEdges = 0; |
| 680 | for (;exp2.More(); exp2.Next()) NbEdges++; |
| 681 | if ( NbEdges == List.Extent()) |
| 682 | { |
| 683 | ListOfWire.Append(Wire); |
| 684 | IsWire = Standard_True; |
| 685 | } |
| 686 | } |
| 687 | } |
| 688 | return IsWire; |
| 689 | } |