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