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