0027045: firsthole & holend commands work incorrectly
[occt.git] / src / BRepFeat / BRepFeat_MakeCylindricalHole.cxx
CommitLineData
b311480e 1// Created on: 1995-05-30
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
18#include <Bnd_Box.hxx>
19#include <BRep_Builder.hxx>
20#include <BRep_Tool.hxx>
42cf5bc1 21#include <BRepBndLib.hxx>
22#include <BRepFeat_MakeCylindricalHole.hxx>
7fd59977 23#include <BRepPrim_Cylinder.hxx>
42cf5bc1 24#include <BRepTools.hxx>
25#include <ElCLib.hxx>
26#include <Geom_Curve.hxx>
27#include <gp_Ax1.hxx>
28#include <LocOpe_CurveShapeIntersector.hxx>
29#include <LocOpe_PntFace.hxx>
30#include <Precision.hxx>
31#include <Standard_ConstructionError.hxx>
32#include <StdFail_NotDone.hxx>
7fd59977 33#include <TopExp_Explorer.hxx>
34#include <TopLoc_Location.hxx>
7fd59977 35#include <TopoDS.hxx>
42cf5bc1 36#include <TopoDS_Shape.hxx>
37#include <TopoDS_Solid.hxx>
38#include <TopTools_ListIteratorOfListOfShape.hxx>
39#include <TopTools_ListOfShape.hxx>
8c31bd38 40#include <BRepAdaptor_Surface.hxx>
41#include <CSLib.hxx>
7fd59977 42
43static void Baryc(const TopoDS_Shape&,
4e57c75e 44 gp_Pnt&);
7fd59977 45
46static void BoxParameters(const TopoDS_Shape&,
4e57c75e 47 const gp_Ax1&,
48 Standard_Real&,
49 Standard_Real&);
7fd59977 50
8c31bd38 51static Standard_Boolean GetOffset(const LocOpe_PntFace& PntInfo,
52 const Standard_Real Radius,
53 const gp_Ax1& Axis,
54 Standard_Real& outOff );
55
56static void CreateCyl(const LocOpe_PntFace& PntInfoFirst, const LocOpe_PntFace& PntInfoLast, const Standard_Real Radius,
57 const gp_Ax1& Axis, TopoDS_Shell& Cyl, TopoDS_Face& CylTopF, TopoDS_Face& CylBottF );
58
7fd59977 59
60//=======================================================================
61//function : Perform
62//purpose :
63//=======================================================================
64
65void BRepFeat_MakeCylindricalHole::Perform(const Standard_Real Radius)
66{
8620e18d 67 const TopoDS_Shape& aObject=myArguments.First();
68 if (aObject.IsNull() || !myAxDef) {
7fd59977 69 Standard_ConstructionError::Raise();
70 }
71
72 myIsBlind = Standard_False;
73 myStatus = BRepFeat_NoError;
74
8620e18d 75 LocOpe_CurveShapeIntersector theASI(myAxis,aObject);
7fd59977 76 if (!theASI.IsDone() || theASI.NbPoints() <= 0) {
77 myStatus = BRepFeat_InvalidPlacement;
78 return;
79 }
7fd59977 80
0d969553 81 // It is not possible to use infinite cylinder for topological operations.
7fd59977 82 Standard_Real PMin,PMax;
8620e18d 83 BoxParameters(aObject,myAxis,PMin,PMax);
7fd59977 84 Standard_Real Heigth = 2.*(PMax-PMin);
85 gp_XYZ theOrig = myAxis.Location().XYZ();
86 theOrig += ((3.*PMin-PMax)/2.) * myAxis.Direction().XYZ();
87 gp_Pnt p1_ao1(theOrig); gp_Ax2 a1_ao1(p1_ao1,myAxis.Direction());
88 BRepPrim_Cylinder theCylinder(a1_ao1,
4e57c75e 89 Radius,
90 Heigth);
7fd59977 91
0d969553 92 // Probably it is better to make cut directly
7fd59977 93
94 BRep_Builder B;
95 TopoDS_Solid theTool;
96 B.MakeSolid(theTool);
97 B.Add(theTool,theCylinder.Shell());
7fd59977 98
99 myTopFace = theCylinder.TopFace();
100 myBotFace = theCylinder.BottomFace();
101 myValidate = Standard_False;
102
103// BRepTools::Dump(theTool,cout);
104 Standard_Boolean Fuse = Standard_False;
4e57c75e 105 //
106 AddTool(theTool);
107 SetOperation(Fuse);
8620e18d 108 BOPAlgo_BOP::Perform();
7fd59977 109}
110
111
112//=======================================================================
113//function : PerformThruNext
114//purpose :
115//=======================================================================
116
117void BRepFeat_MakeCylindricalHole::PerformThruNext(const Standard_Real Radius,
4e57c75e 118 const Standard_Boolean Cont)
7fd59977 119{
8620e18d 120 //
121 const TopoDS_Shape& aObject=myArguments.First();
122 if (aObject.IsNull() || !myAxDef) {
7fd59977 123 Standard_ConstructionError::Raise();
124 }
125
126 myIsBlind = Standard_False;
127 myValidate = Cont;
128 myStatus = BRepFeat_NoError;
129
8620e18d 130 LocOpe_CurveShapeIntersector theASI(myAxis,aObject);
7fd59977 131 if (!theASI.IsDone()) {
132 myStatus = BRepFeat_InvalidPlacement;
133 return;
134 }
135
7fd59977 136 Standard_Integer IndFrom,IndTo;
137 TopAbs_Orientation theOr;
8c31bd38 138 LocOpe_PntFace PntInfoFirst, PntInfoLast;
7fd59977 139 Standard_Boolean ok = theASI.LocalizeAfter(0.,theOr,IndFrom,IndTo);
140 if (ok) {
141 if (theOr == TopAbs_FORWARD) {
8c31bd38 142 PntInfoFirst = theASI.Point(IndFrom);
7fd59977 143 ok = theASI.LocalizeAfter(IndTo,theOr,IndFrom,IndTo);
144 if (ok) {
4e57c75e 145 if (theOr != TopAbs_REVERSED) {
146 ok = Standard_False;
147 }
148 else {
8c31bd38 149 PntInfoLast = theASI.Point(IndTo);
4e57c75e 150 }
7fd59977 151 }
152
153 }
154 else { // TopAbs_REVERSED
8c31bd38 155 PntInfoLast = theASI.Point(IndTo);
7fd59977 156 ok = theASI.LocalizeBefore(IndFrom,theOr,IndFrom,IndTo);
157 if (ok) {
4e57c75e 158 if (theOr != TopAbs_FORWARD) {
159 ok = Standard_False;
160 }
161 else {
8c31bd38 162 PntInfoFirst = theASI.Point(IndFrom);
4e57c75e 163 }
7fd59977 164 }
165 }
166 }
167 if (!ok) {
168 myStatus = BRepFeat_InvalidPlacement;
169 return;
170 }
171
8c31bd38 172 TopoDS_Shell Cyl;
173 CreateCyl(PntInfoFirst, PntInfoLast, Radius, myAxis, Cyl, myTopFace, myBotFace);
7fd59977 174
175 BRep_Builder B;
176 TopoDS_Solid theTool;
177 B.MakeSolid(theTool);
8c31bd38 178 B.Add(theTool, Cyl);
7fd59977 179
7fd59977 180 Standard_Boolean Fuse = Standard_False;
4e57c75e 181 AddTool(theTool);
182 SetOperation(Fuse);
8c31bd38 183 BOPAlgo_BOP::Perform();
4e57c75e 184 TopTools_ListOfShape parts;
185 PartsOfTool(parts);
7fd59977 186
7fd59977 187 Standard_Integer nbparts = 0;
4e57c75e 188 TopTools_ListIteratorOfListOfShape its(parts);
7fd59977 189 for (; its.More(); its.Next()) {
190 nbparts ++;
191 }
192 if (nbparts == 0) {
193 myStatus = BRepFeat_InvalidPlacement;
194 return;
195 }
196
0d969553
Y
197 if (nbparts >= 2) { // preserve the smallest as parameter
198 // along the axis
8c31bd38 199
200 Standard_Real First=PntInfoFirst.Parameter();
201 Standard_Real Last=PntInfoLast.Parameter();
7fd59977 202 TopoDS_Shape tokeep;
203 Standard_Real parbar,parmin = Last;
204 gp_Pnt Barycentre;
4e57c75e 205 for (its.Initialize(parts); its.More(); its.Next()) {
7fd59977 206 Baryc(its.Value(),Barycentre);
207 parbar = ElCLib::LineParameter(myAxis,Barycentre);
208 if (parbar >= First && parbar <= Last && parbar <= parmin) {
4e57c75e 209 parmin = parbar;
210 tokeep = its.Value();
7fd59977 211 }
212 }
213
0d969553 214 if (tokeep.IsNull()) { // preserve the closest interval
7fd59977 215
216 Standard_Real dmin = RealLast();
4e57c75e 217 for (its.Initialize(parts); its.More(); its.Next()) {
218 Baryc(its.Value(),Barycentre);
219 parbar = ElCLib::LineParameter(myAxis,Barycentre);
220 if (parbar < First) {
221 if (First - parbar < dmin ) {
222 dmin = First-parbar;
223 tokeep = its.Value();
224 }
225 else { // parbar > Last
226 if (parbar - Last < dmin) {
227 dmin = parbar-Last;
228 tokeep = its.Value();
229 }
230 }
231 }
7fd59977 232 }
233 }
4e57c75e 234 for (its.Initialize(parts); its.More(); its.Next()) {
4e57c75e 235 if (tokeep.IsSame(its.Value())) {
236 KeepPart(its.Value());
237 break;
7fd59977 238 }
239 }
240 }
7fd59977 241}
242
243//=======================================================================
244//function : PerformUntilEnd
245//purpose :
246//=======================================================================
247
248void BRepFeat_MakeCylindricalHole::PerformUntilEnd(const Standard_Real Radius,
4e57c75e 249 const Standard_Boolean Cont)
7fd59977 250{
8620e18d 251 //
252 const TopoDS_Shape& aObject=myArguments.First();
253 if (aObject.IsNull() || !myAxDef) {
7fd59977 254 Standard_ConstructionError::Raise();
255 }
256
257 myIsBlind = Standard_False;
258 myValidate = Cont;
259 myStatus = BRepFeat_NoError;
260
8620e18d 261 LocOpe_CurveShapeIntersector theASI(myAxis,aObject);
7fd59977 262 if (!theASI.IsDone()) {
263 myStatus = BRepFeat_InvalidPlacement;
264 return;
265 }
8c31bd38 266
7fd59977 267 Standard_Integer IndFrom,IndTo;
268 TopAbs_Orientation theOr;
269 Standard_Boolean ok = theASI.LocalizeAfter(0.,theOr,IndFrom,IndTo);
8c31bd38 270 LocOpe_PntFace PntInfoFirst, PntInfoLast;
271
7fd59977 272 if (ok) {
273 if (theOr == TopAbs_REVERSED) {
0d969553
Y
274 ok = theASI.LocalizeBefore(IndFrom,theOr,IndFrom,IndTo); // on reset
275 // It is possible to search for the next.
7fd59977 276 }
277 if ( ok && theOr == TopAbs_FORWARD) {
8c31bd38 278 PntInfoFirst = theASI.Point(IndFrom);
7fd59977 279 ok = theASI.LocalizeBefore(theASI.NbPoints()+1,theOr,IndFrom,IndTo);
280 if (ok) {
4e57c75e 281 if (theOr != TopAbs_REVERSED) {
282 ok = Standard_False;
283 }
284 else {
8c31bd38 285 PntInfoLast = theASI.Point(IndTo);
4e57c75e 286 }
7fd59977 287 }
288 }
289 }
290 if (!ok) {
291 myStatus = BRepFeat_InvalidPlacement;
292 return;
293 }
294
8c31bd38 295 TopoDS_Shell Cyl;
296 CreateCyl(PntInfoFirst, PntInfoLast, Radius, myAxis, Cyl, myTopFace, myBotFace);
7fd59977 297
298 BRep_Builder B;
299 TopoDS_Solid theTool;
300 B.MakeSolid(theTool);
8c31bd38 301 B.Add(theTool, Cyl);
7fd59977 302
7fd59977 303 Standard_Boolean Fuse = Standard_False;
4e57c75e 304 AddTool(theTool);
305 SetOperation(Fuse);
8c31bd38 306 BOPAlgo_BOP::Perform();
4e57c75e 307 TopTools_ListOfShape parts;
308 PartsOfTool(parts);
7fd59977 309
310 Standard_Integer nbparts = 0;
4e57c75e 311 TopTools_ListIteratorOfListOfShape its(parts);
7fd59977 312 for (; its.More(); its.Next()) {
313 nbparts ++;
314 }
315 if (nbparts == 0) {
316 myStatus = BRepFeat_InvalidPlacement;
317 return;
318 }
319
0d969553 320 if (nbparts >= 2) { // preserve everything above the First
7fd59977 321 Standard_Real parbar;
322 gp_Pnt Barycentre;
4e57c75e 323 for (its.Initialize(parts); its.More(); its.Next()) {
7fd59977 324 Baryc(its.Value(),Barycentre);
325 parbar = ElCLib::LineParameter(myAxis,Barycentre);
8c31bd38 326 if (parbar > PntInfoFirst.Parameter()) {
4e57c75e 327 KeepPart(its.Value());
7fd59977 328 }
329 }
330 }
7fd59977 331}
332
333
334//=======================================================================
335//function : Perform
336//purpose :
337//=======================================================================
338
339void BRepFeat_MakeCylindricalHole::Perform(const Standard_Real Radius,
4e57c75e 340 const Standard_Real PFrom,
341 const Standard_Real PTo,
342 const Standard_Boolean Cont)
7fd59977 343{
8620e18d 344 //
345 const TopoDS_Shape& aObject=myArguments.First();
346 if (aObject.IsNull() || !myAxDef) {
7fd59977 347 Standard_ConstructionError::Raise();
348 }
349
350 myIsBlind = Standard_False;
351 myValidate = Cont;
352 myStatus = BRepFeat_NoError;
353
8620e18d 354 LocOpe_CurveShapeIntersector theASI(myAxis,aObject);
7fd59977 355 if (!theASI.IsDone()) {
356 myStatus = BRepFeat_InvalidPlacement;
357 return;
358 }
359
360 Standard_Real thePFrom,thePTo;
361 if (PFrom < PTo) {
362 thePFrom = PFrom;
363 thePTo = PTo;
364 }
365 else {
366 thePFrom = PTo;
367 thePTo = PFrom;
368 }
369
8c31bd38 370 //Standard_Real First=0,Last=0,prm;
371 LocOpe_PntFace PntInfoFirst, PntInfoLast;
7fd59977 372 Standard_Integer IndFrom,IndTo;
373 TopAbs_Orientation theOr;
374 Standard_Boolean ok = theASI.LocalizeAfter(thePFrom,theOr,IndFrom,IndTo);
375 if (ok) {
376 if (theOr == TopAbs_REVERSED) {
0d969553
Y
377 ok = theASI.LocalizeBefore(IndFrom,theOr,IndFrom,IndTo); // reset
378 // It is possible to find the next.
7fd59977 379 }
380 if ( ok && theOr == TopAbs_FORWARD) {
8c31bd38 381 PntInfoFirst = theASI.Point(IndFrom);
7fd59977 382 ok = theASI.LocalizeBefore(thePTo,theOr,IndFrom,IndTo);
383 if (ok) {
4e57c75e 384 if (theOr == TopAbs_FORWARD) {
385 ok = theASI.LocalizeAfter(IndTo,theOr,IndFrom,IndTo);
386 }
387 if (ok && theOr == TopAbs_REVERSED) {
8c31bd38 388 PntInfoLast = theASI.Point(IndTo);
4e57c75e 389 }
7fd59977 390 }
391 }
392 }
393
394 if (!ok) {
395 myStatus = BRepFeat_InvalidPlacement;
396 return;
397 }
398
8c31bd38 399 TopoDS_Shell Cyl;
400 CreateCyl(PntInfoFirst, PntInfoLast, Radius, myAxis, Cyl, myTopFace, myBotFace);
7fd59977 401
402 BRep_Builder B;
403 TopoDS_Solid theTool;
404 B.MakeSolid(theTool);
8c31bd38 405 B.Add(theTool, Cyl);
7fd59977 406
7fd59977 407 Standard_Boolean Fuse = Standard_False;
4e57c75e 408 AddTool(theTool);
409 SetOperation(Fuse);
8c31bd38 410 BOPAlgo_BOP::Perform();
4e57c75e 411 TopTools_ListOfShape parts;
412 PartsOfTool(parts);
7fd59977 413
414 Standard_Integer nbparts = 0;
4e57c75e 415 TopTools_ListIteratorOfListOfShape its(parts);
7fd59977 416 for (; its.More(); its.Next()) {
417 nbparts ++;
418 }
419 if (nbparts == 0) {
420 myStatus = BRepFeat_InvalidPlacement;
421 return;
422 }
423
0d969553 424 if (nbparts >= 2) { // preserve parts between First and Last
7fd59977 425
426 TopoDS_Shape tokeep;
427 Standard_Real parbar;
428 gp_Pnt Barycentre;
4e57c75e 429 for (its.Initialize(parts); its.More(); its.Next()) {
7fd59977 430 Baryc(its.Value(),Barycentre);
431 parbar = ElCLib::LineParameter(myAxis,Barycentre);
8c31bd38 432 if (!(parbar < PntInfoFirst.Parameter() || parbar > PntInfoLast.Parameter())) {
4e57c75e 433 KeepPart(its.Value());
7fd59977 434 }
435 }
436 }
7fd59977 437}
438
439
440//=======================================================================
441//function : PerformBlind
442//purpose :
443//=======================================================================
444
445void BRepFeat_MakeCylindricalHole::PerformBlind(const Standard_Real Radius,
4e57c75e 446 const Standard_Real Length,
447 const Standard_Boolean Cont)
7fd59977 448{
8620e18d 449 //
450 const TopoDS_Shape& aObject=myArguments.First();
451 if (aObject.IsNull() || !myAxDef || Length <= 0.) {
7fd59977 452 Standard_ConstructionError::Raise();
453 }
454
455 myIsBlind = Standard_True;
456 myValidate = Cont;
457 myStatus = BRepFeat_NoError;
458
8620e18d 459 LocOpe_CurveShapeIntersector theASI(myAxis,aObject);
7fd59977 460 if (!theASI.IsDone()) {
461 myStatus = BRepFeat_InvalidPlacement;
462 return;
463 }
464
7fd59977 465 Standard_Real First;
466 Standard_Integer IndFrom,IndTo;
467 TopAbs_Orientation theOr;
468 Standard_Boolean ok = theASI.LocalizeAfter(0.,theOr,IndFrom,IndTo);
469
470 if (ok) {
471 if (theOr == TopAbs_REVERSED) {
0d969553
Y
472 ok = theASI.LocalizeBefore(IndFrom,theOr,IndFrom,IndTo); // reset
473 // it is possible to find the next
7fd59977 474 }
475 ok = ok && theOr == TopAbs_FORWARD;
476 }
477 if (!ok) {
478 myStatus = BRepFeat_InvalidPlacement;
479 return;
480 }
481
0d969553 482 // check a priori the length of the hole
7fd59977 483 Standard_Integer IFNext,ITNext;
484 ok = theASI.LocalizeAfter(IndTo,theOr,IFNext,ITNext);
485 if (!ok) {
486 myStatus = BRepFeat_InvalidPlacement;
487 return;
488 }
489 if (theASI.Point(IFNext).Parameter() <= Length) {
490 myStatus = BRepFeat_HoleTooLong;
491 return;
492 }
493
494 TopTools_ListOfShape theList;
8c31bd38 495
0d969553 496 // version for advanced control
7fd59977 497 for (Standard_Integer i=IndFrom; i<= ITNext; i++) {
498 theList.Append(theASI.Point(i).Face());
499 }
500
501 First = theASI.Point(IndFrom).Parameter();
502
0d969553 503 //// It is not possible to use infinite cylinder for topological operations.
7fd59977 504 Standard_Real PMin,PMax;
8620e18d 505 BoxParameters(aObject,myAxis,PMin,PMax);
7fd59977 506 if (PMin > Length) {
507 myStatus = BRepFeat_InvalidPlacement;
508 return;
509 }
510
511 Standard_Real Heigth = 3.*(Length-PMin)/2.;
512 gp_XYZ theOrig = myAxis.Location().XYZ();
513 theOrig += ((3.*PMin-Length)/2.) * myAxis.Direction().XYZ();
514 gp_Pnt p5_ao1(theOrig); gp_Ax2 a5_ao1(p5_ao1,myAxis.Direction());
515 BRepPrim_Cylinder theCylinder(a5_ao1,
4e57c75e 516 Radius,
517 Heigth);
7fd59977 518
519 BRep_Builder B;
520 TopoDS_Solid theTool;
521 B.MakeSolid(theTool);
522 B.Add(theTool,theCylinder.Shell());
7fd59977 523
524 myTopFace = theCylinder.TopFace();
525 myBotFace.Nullify();
526
527 // BRepTools::Dump(theTool,cout);
528 Standard_Boolean Fuse = Standard_False;
4e57c75e 529 //myBuilder.Perform(theTool,theList,Fuse);
530 //myBuilder.BuildPartsOfTool();
531 AddTool(theTool);
532 SetOperation(Fuse);
8c31bd38 533 BOPAlgo_BOP::Perform();
4e57c75e 534 TopTools_ListOfShape parts;
535 PartsOfTool(parts);
7fd59977 536
537 Standard_Integer nbparts = 0;
4e57c75e 538 TopTools_ListIteratorOfListOfShape its(parts);
7fd59977 539 for (; its.More(); its.Next()) {
540 nbparts ++;
541 }
542 if (nbparts == 0) {
543 myStatus = BRepFeat_InvalidPlacement;
544 return;
545 }
546
0d969553 547 if (nbparts >= 2) { // preserve the smallest as parameter along the axis
7fd59977 548 TopoDS_Shape tokeep;
549 Standard_Real parbar,parmin = RealLast();
550 gp_Pnt Barycentre;
4e57c75e 551 for (its.Initialize(parts); its.More(); its.Next()) {
7fd59977 552 Baryc(its.Value(),Barycentre);
553 parbar = ElCLib::LineParameter(myAxis,Barycentre);
554 if (parbar >= First && parbar <= parmin) {
4e57c75e 555 parmin = parbar;
556 tokeep = its.Value();
7fd59977 557 }
558 }
559
0d969553 560 if (tokeep.IsNull()) { // preserve the closest interval
7fd59977 561
562 Standard_Real dmin = RealLast();
4e57c75e 563 for (its.Initialize(parts); its.More(); its.Next()) {
564 Baryc(its.Value(),Barycentre);
565 parbar = ElCLib::LineParameter(myAxis,Barycentre);
566 if (Abs(First - parbar) < dmin ) {
567 dmin = Abs(First-parbar);
568 tokeep = its.Value();
569 }
7fd59977 570 }
571 }
4e57c75e 572 for (its.Initialize(parts); its.More(); its.Next()) {
573 if (tokeep.IsSame(its.Value())) {
574 KeepPart(its.Value());
575 break;
7fd59977 576 }
577 }
578 }
7fd59977 579}
580
7fd59977 581//=======================================================================
582//function : Build
583//purpose :
584//=======================================================================
585
586void BRepFeat_MakeCylindricalHole::Build ()
587{
588 if (myStatus == BRepFeat_NoError) {
4e57c75e 589 PerformResult();
590 if (!ErrorStatus()) {
7fd59977 591 myStatus = (myValidate) ? Validate() : BRepFeat_NoError;
592 if (myStatus == BRepFeat_NoError) {
4e57c75e 593 myShape = Shape();
7fd59977 594 }
595 }
596 else {
7fd59977 597 myStatus = BRepFeat_InvalidPlacement; // why not
598 }
599 }
7fd59977 600}
601
602
603//=======================================================================
604//function : Validate
605//purpose :
606//=======================================================================
607
608BRepFeat_Status BRepFeat_MakeCylindricalHole::Validate ()
609{
610 BRepFeat_Status thestat = BRepFeat_NoError;
4e57c75e 611 TopExp_Explorer ex(Shape(),TopAbs_FACE);
0d969553 612 if (myIsBlind) { // limit of the hole
7fd59977 613 for (; ex.More(); ex.Next()) {
614 if (ex.Current().IsSame(myTopFace) ) {
4e57c75e 615 break;
7fd59977 616 }
617 }
618 if (!ex.More()) {
619 thestat = BRepFeat_HoleTooLong;
620 }
621 }
622 else {
623 for (; ex.More(); ex.Next()) {
624 if (ex.Current().IsSame(myTopFace) ) {
4e57c75e 625 return BRepFeat_InvalidPlacement;
7fd59977 626 }
627 }
628 for (ex.ReInit(); ex.More(); ex.Next()) {
629 if (ex.Current().IsSame(myBotFace) ) {
4e57c75e 630 return BRepFeat_InvalidPlacement;
7fd59977 631 }
632 }
633 }
634 return thestat;
635}
636
637
638
639void Baryc(const TopoDS_Shape& S, gp_Pnt& B)
640{
641 TopExp_Explorer exp(S,TopAbs_EDGE);
642 gp_XYZ Bar(0.,0.,0.);
643 TopLoc_Location L;
644 Handle(Geom_Curve) C;
645 Standard_Real prm,First,Last;
646
647 Standard_Integer i, nbp= 0;
648 for (; exp.More(); exp.Next()) {
0d969553 649 // Calculate points by non-degenerated edges
7fd59977 650 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
651 if (!BRep_Tool::Degenerated(E)) {
652 C = BRep_Tool::Curve(E,L,First,Last);
653 C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
654 for (i=1;i<=11; i++) {
4e57c75e 655 prm = ((11-i)*First + (i-1)*Last)/10.;
656 Bar += C->Value(prm).XYZ();
657 nbp++;
7fd59977 658 }
659 }
660 }
661 Bar.Divide((Standard_Real)nbp);
662 B.SetXYZ(Bar);
663}
664
665
666void BoxParameters(const TopoDS_Shape& S,
4e57c75e 667 const gp_Ax1& Axis,
668 Standard_Real& parmin,
669 Standard_Real& parmax)
7fd59977 670{
671
0d969553 672 // calculate the parameters of a bounding box in the direction of the axis of the hole
7fd59977 673 Bnd_Box B;
674 BRepBndLib::Add(S,B);
675 Standard_Real c[6];
676 B.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
677 gp_Pnt P;
678 Standard_Integer i,j,k;
679 parmin = RealLast();
680 parmax = RealFirst();
681 Standard_Real param;
682 for (i=0; i<=1; i++) {
683 P.SetX(c[i]);
684 for (j=2; j<=3; j++) {
685 P.SetY(c[j]);
686 for (k=4; k<=5; k++) {
4e57c75e 687 P.SetZ(c[k]);
688 param = ElCLib::LineParameter(Axis,P);
689 parmin = Min(param,parmin);
690 parmax = Max(param,parmax);
7fd59977 691 }
692 }
693 }
694}
8c31bd38 695
696Standard_Boolean GetOffset(const LocOpe_PntFace& PntInfo, const Standard_Real Radius, const gp_Ax1& Axis, Standard_Real& outOff )
697{
698 const TopoDS_Face& FF = PntInfo.Face();
699 BRepAdaptor_Surface FFA(FF);
700
701 Standard_Real Up = PntInfo.UParameter();
702 Standard_Real Vp = PntInfo.VParameter();
703 gp_Pnt PP;
704 gp_Vec D1U, D1V;
705 FFA.D1(Up, Vp, PP, D1U, D1V);
706 gp_Dir NormF;
707 CSLib_NormalStatus stat;
708 CSLib::Normal(D1U, D1V, Precision::Angular(), stat, NormF);
709 if (stat != CSLib_Defined)
710 return Standard_False;
711 Standard_Real angle = Axis.Direction().Angle(NormF);
712 if (Abs(M_PI/2. - angle) < Precision::Angular())
713 return Standard_False;
714 outOff = Radius * Abs (tan(angle));
715 return Standard_True;
716}
717
718void CreateCyl(const LocOpe_PntFace& PntInfoFirst, const LocOpe_PntFace& PntInfoLast, const Standard_Real Radius,
719 const gp_Ax1& Axis, TopoDS_Shell& Cyl, TopoDS_Face& CylTopF, TopoDS_Face& CylBottF )
720{
721 Standard_Real First=0, Last=0;
722 double offF = 0., offL = 0.;
723 Last = PntInfoLast.Parameter();
724 First = PntInfoFirst.Parameter();
725 Standard_Real Heigth = Last - First;
726
727 if ( !GetOffset(PntInfoFirst, Radius, Axis, offF))
728 offF = Radius;
729 if ( !GetOffset(PntInfoLast, Radius, Axis, offL))
730 offL = Radius;
731
732 //create cylinder along the axis (myAxis);
733 //from 'First - offF' to 'Last + offL' params
734 gp_XYZ theOrig = PntInfoFirst.Pnt().XYZ() - offF * Axis.Direction().XYZ();
735 gp_Pnt p2_ao1(theOrig);
736 gp_Ax2 a2_ao1(p2_ao1, Axis.Direction());
737 BRepPrim_Cylinder theCylinder(a2_ao1, Radius, Heigth + offF + offL);
738 Cyl = theCylinder.Shell();
739 CylTopF = theCylinder.TopFace();
740 CylBottF = theCylinder.BottomFace();
741}