1 // Created on: 1996-02-13
2 // Created by: Olga KOULECHOVA
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bnd_Box.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAlgo.hxx>
21 #include <BRepAlgoAPI_BooleanOperation.hxx>
22 #include <BRepAlgoAPI_Cut.hxx>
23 #include <BRepAlgoAPI_Fuse.hxx>
24 #include <BRepBndLib.hxx>
25 #include <BRepCheck_Analyzer.hxx>
26 #include <BRepFeat.hxx>
27 #include <BRepFeat_Builder.hxx>
28 #include <BRepFeat_Form.hxx>
29 #include <BRepLib.hxx>
30 #include <BRepTools_Modifier.hxx>
31 #include <BRepTools_TrsfModification.hxx>
33 #include <Geom_ConicalSurface.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_CylindricalSurface.hxx>
36 #include <Geom_Plane.hxx>
37 #include <Geom_RectangularTrimmedSurface.hxx>
39 #include <LocOpe_BuildShape.hxx>
40 #include <LocOpe_CSIntersector.hxx>
41 #include <LocOpe_FindEdges.hxx>
42 #include <LocOpe_Gluer.hxx>
43 #include <LocOpe_PntFace.hxx>
44 #include <LocOpe_SequenceOfCirc.hxx>
45 #include <Precision.hxx>
46 #include <Standard_NoSuchObject.hxx>
47 #include <TColgp_SequenceOfPnt.hxx>
48 #include <TopExp_Explorer.hxx>
50 #include <TopoDS_Compound.hxx>
51 #include <TopoDS_Shape.hxx>
52 #include <TopoDS_Solid.hxx>
53 #include <TopOpeBRepBuild_HBuilder.hxx>
54 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
55 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TopTools_MapIteratorOfMapOfShape.hxx>
58 #include <TopTools_MapOfShape.hxx>
60 //modified by NIZNHY-PKV Thu Mar 21 17:30:25 2002 f
61 //#include <BRepAlgo_Cut.hxx>
62 //#include <BRepAlgo_Fuse.hxx>
63 //modified by NIZNHY-PKV Thu Mar 21 17:30:29 2002 t
65 extern Standard_Boolean BRepFeat_GettraceFEAT();
68 static void Descendants(const TopoDS_Shape&,
70 TopTools_MapOfShape&);
72 //=======================================================================
74 //purpose : topological reconstruction of the result
75 //=======================================================================
76 void BRepFeat_Form::GlobalPerform ()
80 Standard_Boolean trc = BRepFeat_GettraceFEAT();
81 if (trc) cout << "BRepFeat_Form::GlobalPerform ()" << endl;
84 if (!mySbOK || !myGSOK || !mySFOK || !mySUOK || !myGFOK ||
87 if (trc) cout << " Fields not initialized in BRepFeat_Form" << endl;
89 myStatusError = BRepFeat_NotInitialized;
95 TopExp_Explorer exp,exp2;
96 Standard_Integer theOpe = 2;
97 TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
99 if(myJustFeat && !myFuse) {
101 if (trc) cout << " Invalid option : myJustFeat + Cut" << endl;
103 myStatusError = BRepFeat_InvOption;
107 else if(myJustFeat) {
110 else if (!myGluedF.IsEmpty()) {
114 Standard_Boolean ChangeOpe = Standard_False;
116 Standard_Boolean FromInShape = Standard_False;
117 Standard_Boolean UntilInShape = Standard_False;
119 if (!mySFrom.IsNull()) {
120 FromInShape = Standard_True;
121 for (exp2.Init(mySFrom,TopAbs_FACE); exp2.More(); exp2.Next()) {
122 const TopoDS_Shape& ffrom = exp2.Current();
123 for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
124 if (exp.Current().IsSame(ffrom)) {
129 FromInShape = Standard_False;
131 if (trc) cout << " From not in Shape" << endl;
138 if (!mySUntil.IsNull()) {
139 UntilInShape = Standard_True;
140 for (exp2.Init(mySUntil,TopAbs_FACE); exp2.More(); exp2.Next()) {
141 const TopoDS_Shape& funtil = exp2.Current();
142 for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
143 if (exp.Current().IsSame(funtil)) {
148 UntilInShape = Standard_False;
150 if (trc) cout << " Until not in Shape" << endl;
157 TopTools_ListIteratorOfListOfShape it,it2;
158 Standard_Integer sens = 0;
160 TColGeom_SequenceOfCurve scur;
163 Standard_Real mf, Mf, mu, Mu;
165 TopAbs_Orientation Orifuntil = TopAbs_INTERNAL;
166 TopAbs_Orientation Oriffrom = TopAbs_INTERNAL;
167 TopoDS_Face FFrom,FUntil;
169 LocOpe_CSIntersector ASI1;
170 LocOpe_CSIntersector ASI2;
172 TopTools_ListOfShape IntList;
175 //--- 1) by intersection
177 // Intersection Tool Shape From
178 if (!mySFrom.IsNull()) {
183 // Intersection Tool Shape Until
184 if (!mySUntil.IsNull()) {
190 // Find sens, FFrom, FUntil
191 for (Standard_Integer jj=1; jj<=scur.Length(); jj++) {
192 if (ASI1.IsDone() && ASI2.IsDone()) {
193 if (ASI1.NbPoints(jj) <= 0) {
196 mf = ASI1.Point(jj,1).Parameter();
197 Mf = ASI1.Point(jj,ASI1.NbPoints(jj)).Parameter();
198 if (ASI2.NbPoints(jj) <= 0) {
201 mu = ASI2.Point(jj,1).Parameter();
202 Mu = ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter();
203 if (!scur(jj)->IsPeriodic()) {
204 Standard_Integer ku, kf;
205 if (! (mu > Mf || mf > Mu)) { //overlapping intervals
208 ku = ASI2.NbPoints(jj);
212 myStatusError = BRepFeat_IntervalOverlap;
218 ku = ASI2.NbPoints(jj);
222 myStatusError = BRepFeat_IntervalOverlap;
227 kf = ASI1.NbPoints(jj);
230 if (Oriffrom == TopAbs_INTERNAL) {
231 TopAbs_Orientation Oript = ASI1.Point(jj,kf).Orientation();
232 if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
234 Oript = TopAbs::Reverse(Oript);
236 Oriffrom = TopAbs::Reverse(Oript);
237 FFrom = ASI1.Point(jj,kf).Face();
240 if (Orifuntil == TopAbs_INTERNAL) {
241 TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
242 if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
244 Oript = TopAbs::Reverse(Oript);
247 FUntil = ASI2.Point(jj,ku).Face();
252 else if (ASI2.IsDone()) {
253 if (ASI2.NbPoints(jj) <= 0)
256 // for base case prism on mySUntil -> ambivalent direction
257 // -> preferrable direction = 1
259 if (ASI2.Point(jj,1).Parameter()*
260 ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter()<=0)
262 else if (ASI2.Point(jj,1).Parameter()<0.)
273 ku = ASI2.NbPoints(jj);
275 if (Orifuntil == TopAbs_INTERNAL && sens != 0) {
276 TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
277 if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
279 Oript = TopAbs::Reverse(Oript);
282 FUntil = ASI2.Point(jj,ku).Face();
293 LocOpe_Gluer theGlue;
299 if (trc) cout << " Gluer" << endl;
301 Standard_Boolean Collage = Standard_True;
302 // cut by FFrom && FUntil
305 B.MakeCompound(TopoDS::Compound(Comp));
306 if (!mySFrom.IsNull()) {
307 TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
312 if (!mySUntil.IsNull()) {
313 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
319 LocOpe_FindEdges theFE;
320 TopTools_DataMapOfShapeListOfShape locmap;
321 TopExp_Explorer expp(Comp, TopAbs_SOLID);
322 if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
323 //modified by NIZNHY-PKV Thu Mar 21 17:15:36 2002 f
324 //BRepAlgo_Cut trP(myGShape,Comp);
325 BRepAlgoAPI_Cut trP(myGShape, Comp);
326 //modified by NIZNHY-PKV Thu Mar 21 17:15:58 2002 t
327 exp.Init(trP.Shape(), TopAbs_SOLID);
328 if (exp.Current().IsNull()) {
330 ChangeOpe = Standard_True;
331 Collage = Standard_False;
334 // Only solids are preserved
335 TopoDS_Shape theGShape;
336 B.MakeCompound(TopoDS::Compound(theGShape));
337 for (; exp.More(); exp.Next()) {
338 B.Add(theGShape,exp.Current());
340 if (!BRepAlgo::IsValid(theGShape)) {
342 ChangeOpe = Standard_True;
343 Collage = Standard_False;
346 if(!mySFrom.IsNull()) {
348 ex.Init(mySFrom, TopAbs_FACE);
349 for(; ex.More(); ex.Next()) {
350 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
352 TopTools_ListOfShape thelist;
353 myMap.Bind(fac, thelist);
356 TopTools_ListOfShape thelist1;
357 locmap.Bind(fac, thelist1);
359 if (trP.IsDeleted(fac)) {
361 else if (!FromInShape) {
362 myMap(fac) = trP.Modified(fac);
363 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
366 locmap(fac) =trP.Modified(fac) ;
367 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
370 }// if(!mySFrom.IsNull())
372 if(!mySUntil.IsNull()) {
374 ex.Init(mySUntil, TopAbs_FACE);
375 for(; ex.More(); ex.Next()) {
376 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
378 TopTools_ListOfShape thelist2;
379 myMap.Bind(fac,thelist2);
382 TopTools_ListOfShape thelist3;
383 locmap.Bind(fac,thelist3);
385 if (trP.IsDeleted(fac)) {
387 else if (!UntilInShape) {
388 myMap(fac) = trP.Modified(fac);
389 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
392 locmap(fac) = trP.Modified(fac);
393 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
396 }// if(!mySUntil.IsNull())
398 //modified by NIZNHY-PKV Thu Mar 21 17:21:49 2002 f
399 //UpdateDescendants(trP.Builder(),theGShape,Standard_True); // skip faces
400 UpdateDescendants(trP,theGShape,Standard_True); // skip faces
401 //modified by NIZNHY-PKV Thu Mar 21 17:22:32 2002 t
403 theGlue.Init(mySbase,theGShape);
404 for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
405 const TopoDS_Face& gl = TopoDS::Face(itm.Key());
406 TopTools_ListOfShape ldsc;
407 if (trP.IsDeleted(gl)) {
410 ldsc = trP.Modified(gl);
411 if (ldsc.IsEmpty()) ldsc.Append(gl);
413 const TopoDS_Face& glface = TopoDS::Face(itm.Value());
414 for (it.Initialize(ldsc);it.More();it.Next()) {
415 const TopoDS_Face& fac = TopoDS::Face(it.Value());
416 Collage = BRepFeat::IsInside(fac, glface);
419 ChangeOpe = Standard_True;
423 theGlue.Bind(fac,glface);
424 theFE.Set(fac,glface);
425 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
426 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
433 }// if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())
435 theGlue.Init(mySbase,myGShape);
436 for (itm.Initialize(myGluedF); itm.More();itm.Next()) {
437 const TopoDS_Face& glface = TopoDS::Face(itm.Key());
438 const TopoDS_Face& fac = TopoDS::Face(myGluedF(glface));
439 for (exp.Init(myGShape,TopAbs_FACE); exp.More(); exp.Next()) {
440 if (exp.Current().IsSame(glface)) {
445 Collage = BRepFeat::IsInside(glface, fac);
448 ChangeOpe = Standard_True;
452 theGlue.Bind(glface, fac);
453 theFE.Set(glface, fac);
454 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
455 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
462 // Add gluing on start and end face if necessary !!!
463 if (FromInShape && Collage) {
464 TopExp_Explorer ex(mySFrom,TopAbs_FACE);
465 for(; ex.More(); ex.Next()) {
466 const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
467 // for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
468 for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
469 const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
470 theFE.Set(fac1, fac2);
471 theGlue.Bind(fac1, fac2);
472 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
473 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
476 // myMap.UnBind(fac2);
480 if (UntilInShape && Collage) {
481 TopExp_Explorer ex(mySUntil, TopAbs_FACE);
482 for(; ex.More(); ex.Next()) {
483 const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
484 // for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
485 for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
486 const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
487 theGlue.Bind(fac1, fac2);
488 theFE.Set(fac1, fac2);
489 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
490 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
493 //myMap.UnBind(fac2); // to avoid fac2 in Map when
494 // UpdateDescendants(theGlue) is called
498 LocOpe_Operation ope = theGlue.OpeType();
499 if (ope == LocOpe_INVALID ||
500 (myFuse && ope != LocOpe_FUSE) ||
501 (!myFuse && ope != LocOpe_CUT) ||
504 ChangeOpe = Standard_True;
508 //--- if the gluing is always applicable
512 if (trc) cout << " still Gluer" << endl;
515 if (theGlue.IsDone()) {
516 TopoDS_Shape shshs = theGlue.ResultingShape();
517 // if (BRepOffsetAPI::IsTopologicallyValid(shshs)) {
518 if (BRepAlgo::IsValid(shshs)) {
519 UpdateDescendants(theGlue);
520 myNewEdges = theGlue.Edges();
521 myTgtEdges = theGlue.TgtEdges();
523 if (trc) cout << " Gluer result" << endl;
526 myShape = theGlue.ResultingShape();
530 ChangeOpe = Standard_True;
535 ChangeOpe = Standard_True;
540 //--- case without gluing + Tool with proper dimensions
542 if (theOpe == 2 && ChangeOpe && myJustGluer) {
544 if (trc) cout << " Gluer failure" << endl;
546 myJustGluer = Standard_False;
552 //--- case without gluing
556 if (trc) cout << " No Gluer" << endl;
558 TopoDS_Shape theGShape = myGShape;
561 if (trc) cout << " Passage to topological operations" << endl;
567 B.MakeCompound(TopoDS::Compound(Comp));
568 if (!mySFrom.IsNull() || !mySUntil.IsNull()) {
569 if (!mySFrom.IsNull() && !FromInShape) {
570 TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
575 if (!mySUntil.IsNull() && !UntilInShape) {
576 if (!mySFrom.IsNull()) {
577 if (!mySFrom.IsSame(mySUntil)) {
578 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
585 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
593 // update type of selection
594 if(myPerfSelection == BRepFeat_SelectionU && !UntilInShape) {
595 myPerfSelection = BRepFeat_NoSelection;
597 else if(myPerfSelection == BRepFeat_SelectionFU &&
598 !FromInShape && !UntilInShape) {
599 myPerfSelection = BRepFeat_NoSelection;
601 else if(myPerfSelection == BRepFeat_SelectionShU && !UntilInShape) {
602 myPerfSelection = BRepFeat_NoSelection;
606 TopExp_Explorer expp(Comp, TopAbs_SOLID);
607 if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
608 //modified by NIZNHY-PKV Thu Mar 21 17:24:52 2002 f
609 //BRepAlgo_Cut trP(myGShape,Comp);
610 BRepAlgoAPI_Cut trP(myGShape, Comp);
611 //modified by NIZNHY-PKV Thu Mar 21 17:24:56 2002 t
612 // the result is necessarily a compound.
613 exp.Init(trP.Shape(),TopAbs_SOLID);
615 myStatusError = BRepFeat_EmptyCutResult;
619 // Only solids are preserved
621 B.MakeCompound(TopoDS::Compound(theGShape));
622 for (; exp.More(); exp.Next()) {
623 B.Add(theGShape,exp.Current());
625 if (!BRepAlgo::IsValid(theGShape)) {
626 myStatusError = BRepFeat_InvShape;
630 if(!mySFrom.IsNull()) {
632 TopExp_Explorer ex(mySFrom, TopAbs_FACE);
633 for(; ex.More(); ex.Next()) {
634 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
635 TopTools_ListOfShape thelist4;
636 myMap.Bind(fac,thelist4);
637 if (trP.IsDeleted(fac)) {
640 myMap(fac) = trP.Modified(fac);
641 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
646 if(!mySUntil.IsNull()) {
648 TopExp_Explorer ex(mySUntil, TopAbs_FACE);
649 for(; ex.More(); ex.Next()) {
650 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
651 TopTools_ListOfShape thelist5;
652 myMap.Bind(fac,thelist5);
653 if (trP.IsDeleted(fac)) {
656 myMap(fac) = trP.Modified(fac);
657 if (myMap.IsEmpty()) myMap(fac).Append(fac);
662 //modified by NIZNHY-PKV Thu Mar 21 17:27:23 2002 f
663 //UpdateDescendants(trP.Builder(),theGShape,Standard_True);
664 UpdateDescendants(trP,theGShape,Standard_True);
665 //modified by NIZNHY-PKV Thu Mar 21 17:27:31 2002 t
666 }//if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
669 //--- generation of "just feature" for assembly = Parts of tool
670 Standard_Boolean bFlag = (myPerfSelection == BRepFeat_NoSelection) ? 0 : 1;
671 BRepFeat_Builder theBuilder;
672 theBuilder.Init(mySbase, theGShape);
673 theBuilder.SetOperation(myFuse, bFlag);
674 theBuilder.Perform();
676 TopTools_ListOfShape lshape;
677 theBuilder.PartsOfTool(lshape);
679 Standard_Real pbmin = RealLast(), pbmax = RealFirst();
680 Standard_Real prmin = RealLast() - 2*Precision::Confusion();
681 Standard_Real prmax = RealFirst() + 2*Precision::Confusion();
682 Standard_Boolean flag1 = Standard_False;
683 Handle(Geom_Curve) C;
685 //--- Selection of pieces of tool to be preserved
686 if(!lshape.IsEmpty() && myPerfSelection != BRepFeat_NoSelection) {
687 // Find ParametricMinMax depending on the constraints of Shape From and Until
688 // -> prmin, prmax, pbmin and pbmax
691 myStatusError = BRepFeat_EmptyBaryCurve;
696 if(myPerfSelection == BRepFeat_SelectionSh) {
697 BRepFeat::ParametricMinMax(mySbase,C,
698 prmin, prmax, pbmin, pbmax, flag1);
700 else if(myPerfSelection == BRepFeat_SelectionFU) {
701 Standard_Real prmin1, prmax1, prmin2, prmax2;
702 Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
704 BRepFeat::ParametricMinMax(mySFrom,C,
705 prmin1, prmax1, prbmin1, prbmax1, flag1);
706 BRepFeat::ParametricMinMax(mySUntil,C,
707 prmin2, prmax2, prbmin2, prbmax2, flag1);
709 // case of revolutions
710 if (C->IsPeriodic()) {
711 Standard_Real period = C->Period();
714 prmin = ElCLib::InPeriod(prmin1,prmax-period,prmax);
717 prmin = Min(prmin1, prmin2);
720 pbmin = ElCLib::InPeriod(prbmin1,pbmax-period,pbmax);
723 prmin = Min(prmin1, prmin2);
724 prmax = Max(prmax1, prmax2);
725 pbmin = Min(prbmin1, prbmin2);
726 pbmax = Max(prbmax1, prbmax2);
729 else if(myPerfSelection == BRepFeat_SelectionShU) {
730 Standard_Real prmin1, prmax1, prmin2, prmax2;
731 Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
733 if(!myJustFeat && sens == 0) sens =1;
735 myStatusError = BRepFeat_IncDirection;
740 BRepFeat::ParametricMinMax(mySUntil,C,
741 prmin1, prmax1, prbmin1, prbmax1, flag1);
743 BRepFeat::ParametricMinMax(mySbase,C,
744 prmin2, prmax2, prbmin2, prbmax2, flag1);
751 else if (sens == -1) {
758 else if (myPerfSelection == BRepFeat_SelectionU) {
759 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
761 myStatusError = BRepFeat_IncDirection;
766 // Find parts of the tool containing descendants of Shape Until
767 BRepFeat::ParametricMinMax(mySUntil,C,
768 prmin1, prmax1, prbmin1, prbmax1, flag1);
775 else if(sens == -1) {
784 // Finer choice of ParametricMinMax in case when the tool
785 // intersects Shapes From and Until
786 // case of several intersections (keep PartsOfTool according to the selection)
787 // position of the face of intersection in PartsOfTool (before or after)
788 Standard_Real delta = Precision::Confusion();
790 if (myPerfSelection != BRepFeat_NoSelection) {
791 // modif of the test for cts21181 : (prbmax2 and prnmin2) -> (prbmin1 and prbmax1)
792 // correction take into account flag2 for pro15323 and flag3 for pro16060
793 if (!mySUntil.IsNull()) {
794 TopTools_MapOfShape mapFuntil;
795 Descendants(mySUntil,theBuilder,mapFuntil);
796 if (!mapFuntil.IsEmpty()) {
797 for (it.Initialize(lshape); it.More(); it.Next()) {
798 TopExp_Explorer expf;
799 for (expf.Init(it.Value(),TopAbs_FACE);
800 expf.More(); expf.Next()) {
801 if (mapFuntil.Contains(expf.Current())) {
802 Standard_Boolean flag2,flag3;
803 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
804 Standard_Real prmin2, prmax2, prbmin2, prbmax2;
805 BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
806 prbmin1, prbmax1,flag3);
807 BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
808 prbmin2, prbmax2,flag2);
810 Standard_Boolean testOK = !flag2;
813 if (flag1 && prmax2 > prmin + delta) {
815 if (flag3 && prmax1 == prmax2) {
816 testOK = Standard_True;
820 if (prbmin1 < pbmax && testOK) {
828 else if (sens == -1){
829 Standard_Boolean testOK = !flag2;
832 if (flag1 && prmin2 < prmax - delta) {
834 if (flag3 && prmin1 == prmin2) {
835 testOK = Standard_True;
839 if (prbmax1 > pbmin && testOK) {
851 it.Initialize(lshape);
854 if (!mySFrom.IsNull()) {
855 TopTools_MapOfShape mapFfrom;
856 Descendants(mySFrom, theBuilder, mapFfrom);
857 if (!mapFfrom.IsEmpty()) {
858 for (it.Initialize(lshape); it.More(); it.Next()) {
859 TopExp_Explorer expf;
860 for (expf.Init(it.Value(),TopAbs_FACE);
861 expf.More(); expf.Next()) {
862 if (mapFfrom.Contains(expf.Current())) {
863 Standard_Boolean flag2,flag3;
864 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
865 Standard_Real prmin2, prmax2, prbmin2, prbmax2;
866 BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
867 prbmin1, prbmax1,flag3);
868 BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
869 prbmin2, prbmax2,flag2);
871 Standard_Boolean testOK = !flag2;
874 if (flag1 && prmin2 < prmax - delta) {
876 if (flag3 && prmin1 == prmin2) {
877 testOK = Standard_True;
881 if (prbmax1 > pbmin && testOK) {
889 else if (sens == -1){
890 Standard_Boolean testOK = !flag2;
893 if (flag1 && prmax2 > prmin + delta) {
895 if (flag3 && prmax1 == prmax2) {
896 testOK = Standard_True;
900 if (prbmin1 < pbmax && testOK) {
912 it.Initialize(lshape);
918 // Parse PartsOfTool to preserve or not depending on ParametricMinMax
920 Standard_Boolean KeepParts = Standard_False;
921 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
922 Standard_Real min, max, pmin, pmax;
923 Standard_Boolean flag2;
924 for (it.Initialize(lshape); it.More(); it.Next()) {
925 if (C->IsPeriodic()) {
926 Standard_Real period = C->Period();
927 Standard_Real pr, prb;
928 BRepFeat::ParametricMinMax(it.Value(),C, pr, prmax1,
929 prb, prbmax1,flag2,Standard_True);
931 prmin1 = ElCLib::InPeriod(pr,prmax1-period,prmax1);
936 prbmin1 = ElCLib::InPeriod(prb,prbmax1-period,prbmax1);
939 BRepFeat::ParametricMinMax(it.Value(),C,
940 prmin1, prmax1, prbmin1, prbmax1,flag2);
942 if(flag2 == Standard_False || flag1 == Standard_False) {
954 if (!((min > pmax - delta) ||
955 (max < pmin + delta))) {
956 KeepParts = Standard_True;
957 const TopoDS_Shape& S = it.Value();
958 theBuilder.KeepPart(S);
962 // Case when no part of the tool is preserved
965 if (trc) cout << " No parts of tool kept" << endl;
967 myStatusError = BRepFeat_NoParts;
973 // case JustFeature -> all PartsOfTool are preserved
974 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
975 Standard_Real min, max, pmin, pmax;
976 Standard_Boolean flag2;
978 B.MakeCompound(TopoDS::Compound(Compo));
979 for (it.Initialize(lshape); it.More(); it.Next()) {
980 BRepFeat::ParametricMinMax(it.Value(),C,
981 prmin1, prmax1, prbmin1, prbmax1,flag2);
982 if(flag2 == Standard_False || flag1 == Standard_False) {
994 if ((min < pmax - delta) &&
995 (max > pmin + delta)){
996 if (!it.Value().IsNull()) {
997 B.Add(Compo,it.Value());
1005 //--- Generation of result myShape
1008 // removal of edges of section that have no common vertices
1009 // with PartsOfTool preserved
1010 //modified by NIZHNY-EMV Thu May 10 15:56:24 2012
1012 theBuilder.PerformResult();
1013 myShape = theBuilder.Shape();
1015 myShape = theBuilder.Shape();
1017 //modified by NIZHNY-EMV Thu May 10 15:56:26 2012
1021 // all is already done
1026 myStatusError = BRepFeat_OK;
1029 //=======================================================================
1030 //function : IsDeleted
1032 //=======================================================================
1034 Standard_Boolean BRepFeat_Form::IsDeleted(const TopoDS_Shape& F)
1036 return (myMap(F).IsEmpty());
1039 //=======================================================================
1040 //function : Modified
1042 //=======================================================================
1044 const TopTools_ListOfShape& BRepFeat_Form::Modified
1045 (const TopoDS_Shape& F)
1047 if (myMap.IsBound(F)) {
1048 static TopTools_ListOfShape list;
1049 list.Clear(); // For the second passage DPF
1050 TopTools_ListIteratorOfListOfShape ite(myMap(F));
1051 for(; ite.More(); ite.Next()) {
1052 const TopoDS_Shape& sh = ite.Value();
1058 return myGenerated; // empty list
1061 //=======================================================================
1062 //function : Generated
1064 //=======================================================================
1066 const TopTools_ListOfShape& BRepFeat_Form::Generated
1067 (const TopoDS_Shape& S)
1069 if (myMap.IsBound(S) &&
1070 S.ShapeType() != TopAbs_FACE) { // check if filter on face or not
1071 static TopTools_ListOfShape list;
1072 list.Clear(); // For the second passage DPF
1073 TopTools_ListIteratorOfListOfShape ite(myMap(S));
1074 for(; ite.More(); ite.Next()) {
1075 const TopoDS_Shape& sh = ite.Value();
1081 else return myGenerated;
1086 //=======================================================================
1087 //function : UpdateDescendants
1089 //=======================================================================
1091 void BRepFeat_Form::UpdateDescendants(const LocOpe_Gluer& G)
1093 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1094 TopTools_ListIteratorOfListOfShape it,it2;
1095 TopTools_MapIteratorOfMapOfShape itm;
1097 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1098 const TopoDS_Shape& orig = itdm.Key();
1099 TopTools_MapOfShape newdsc;
1100 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1101 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1102 for (it2.Initialize(G.DescendantFaces(fdsc));
1103 it2.More();it2.Next()) {
1104 newdsc.Add(it2.Value());
1107 myMap.ChangeFind(orig).Clear();
1108 for (itm.Initialize(newdsc);itm.More();itm.Next()) {
1109 myMap.ChangeFind(orig).Append(itm.Key());
1118 //=======================================================================
1119 //function : FirstShape
1121 //=======================================================================
1123 const TopTools_ListOfShape& BRepFeat_Form::FirstShape() const
1125 if (!myFShape.IsNull()) {
1126 return myMap(myFShape);
1128 return myGenerated; // empty list
1132 //=======================================================================
1133 //function : LastShape
1135 //=======================================================================
1137 const TopTools_ListOfShape& BRepFeat_Form::LastShape() const
1139 if (!myLShape.IsNull()) {
1140 return myMap(myLShape);
1142 return myGenerated; // empty list
1146 //=======================================================================
1147 //function : NewEdges
1149 //=======================================================================
1151 const TopTools_ListOfShape& BRepFeat_Form::NewEdges() const
1157 //=======================================================================
1158 //function : NewEdges
1160 //=======================================================================
1162 const TopTools_ListOfShape& BRepFeat_Form::TgtEdges() const
1168 //=======================================================================
1169 //function : TransformSUntil
1170 //purpose : Limitation of the shape until the case of infinite faces
1171 //=======================================================================
1173 Standard_Boolean BRepFeat_Form::TransformShapeFU(const Standard_Integer flag)
1176 Standard_Boolean trc = BRepFeat_GettraceFEAT();
1178 Standard_Boolean Trf = Standard_False;
1180 TopoDS_Shape shapefu;
1188 TopExp_Explorer exp(shapefu, TopAbs_FACE);
1189 if (!exp.More()) { // no faces... It is necessary to return an error
1191 if (trc) cout << " BRepFeat_Form::TransformShapeFU : invalid Shape" << endl;
1197 if (!exp.More()) { // the only face. Is it infinite?
1199 TopoDS_Face fac = TopoDS::Face(exp.Current());
1201 Handle(Geom_Surface) S = BRep_Tool::Surface(fac);
1202 Handle(Standard_Type) styp = S->DynamicType();
1203 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1204 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
1205 styp = S->DynamicType();
1208 if (styp == STANDARD_TYPE(Geom_Plane) ||
1209 styp == STANDARD_TYPE(Geom_CylindricalSurface) ||
1210 styp == STANDARD_TYPE(Geom_ConicalSurface)) {
1211 TopExp_Explorer exp1(fac, TopAbs_WIRE);
1213 Trf = Standard_True;
1216 Trf = BRep_Tool::NaturalRestriction(fac);
1221 BRepFeat::FaceUntil(mySbase, fac);
1225 TopTools_ListOfShape thelist6;
1226 myMap.Bind(mySFrom,thelist6);
1227 myMap(mySFrom).Append(fac);
1230 else if(flag == 1) {
1231 TopTools_ListOfShape thelist7;
1232 myMap.Bind(mySUntil,thelist7);
1233 myMap(mySUntil).Append(fac);
1240 for (exp.ReInit(); exp.More(); exp.Next()) {
1241 const TopoDS_Shape& fac = exp.Current();
1242 TopTools_ListOfShape thelist8;
1243 myMap.Bind(fac,thelist8);
1244 myMap(fac).Append(fac);
1249 if (Trf && (flag == 0)) cout << " TransformShapeFU From" << endl;
1250 if (Trf && (flag == 1)) cout << " TransformShapeFU Until" << endl;
1257 //=======================================================================
1258 //function : CurrentStatusError
1260 //=======================================================================
1262 BRepFeat_StatusError BRepFeat_Form::CurrentStatusError() const
1264 return myStatusError;
1267 //=======================================================================
1268 //function : Descendants
1270 //=======================================================================
1272 static void Descendants(const TopoDS_Shape& S,
1273 BRepFeat_Builder& theFB,
1274 TopTools_MapOfShape& mapF)
1277 TopTools_ListIteratorOfListOfShape it;
1278 TopExp_Explorer exp;
1279 for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1281 const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1282 const TopTools_ListOfShape& aLM=theFB.Modified(fdsc);
1284 for (; it.More(); it.Next()) {
1285 mapF.Add(it.Value());
1291 //=======================================================================
1292 //function : UpdateDescendants
1294 //=======================================================================
1295 void BRepFeat_Form::UpdateDescendants(const Handle(TopOpeBRepBuild_HBuilder)& B,
1296 const TopoDS_Shape& S,
1297 const Standard_Boolean SkipFace)
1299 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1300 TopTools_ListIteratorOfListOfShape it,it2;
1301 TopTools_MapIteratorOfMapOfShape itm;
1302 TopExp_Explorer exp;
1304 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1305 const TopoDS_Shape& orig = itdm.Key();
1306 if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1309 TopTools_MapOfShape newdsc;
1311 if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1313 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1314 const TopoDS_Shape& sh = it.Value();
1315 if(sh.ShapeType() != TopAbs_FACE) continue;
1316 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1317 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1318 if (exp.Current().IsSame(fdsc)) { // preserved
1324 if (B->IsSplit(fdsc, TopAbs_OUT)) {
1325 for (it2.Initialize(B->Splits(fdsc,TopAbs_OUT));
1326 it2.More();it2.Next()) {
1327 newdsc.Add(it2.Value());
1330 if (B->IsSplit(fdsc, TopAbs_IN)) {
1331 for (it2.Initialize(B->Splits(fdsc,TopAbs_IN));
1332 it2.More();it2.Next()) {
1333 newdsc.Add(it2.Value());
1336 if (B->IsSplit(fdsc, TopAbs_ON)) {
1337 for (it2.Initialize(B->Splits(fdsc,TopAbs_ON));
1338 it2.More();it2.Next()) {
1339 newdsc.Add(it2.Value());
1342 if (B->IsMerged(fdsc, TopAbs_OUT)) {
1343 for (it2.Initialize(B->Merged(fdsc,TopAbs_OUT));
1344 it2.More();it2.Next()) {
1345 newdsc.Add(it2.Value());
1348 if (B->IsMerged(fdsc, TopAbs_IN)) {
1349 for (it2.Initialize(B->Merged(fdsc,TopAbs_IN));
1350 it2.More();it2.Next()) {
1351 newdsc.Add(it2.Value());
1354 if (B->IsMerged(fdsc, TopAbs_ON)) {
1355 for (it2.Initialize(B->Merged(fdsc,TopAbs_ON));
1356 it2.More();it2.Next()) {
1357 newdsc.Add(it2.Value());
1362 myMap.ChangeFind(orig).Clear();
1363 for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1364 // check the appartenance to the shape...
1365 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1366 if (exp.Current().IsSame(itm.Key())) {
1367 // const TopoDS_Shape& sh = itm.Key();
1368 myMap.ChangeFind(orig).Append(itm.Key());
1375 //modified by NIZNHY-PKV Thu Mar 21 18:43:18 2002 f
1376 //=======================================================================
1377 //function : UpdateDescendants
1379 //=======================================================================
1380 void BRepFeat_Form::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
1381 const TopoDS_Shape& S,
1382 const Standard_Boolean SkipFace)
1384 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1385 TopTools_ListIteratorOfListOfShape it,it2;
1386 TopTools_MapIteratorOfMapOfShape itm;
1387 TopExp_Explorer exp;
1389 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1390 const TopoDS_Shape& orig = itdm.Key();
1391 if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1394 TopTools_MapOfShape newdsc;
1396 if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1398 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1399 const TopoDS_Shape& sh = it.Value();
1400 if(sh.ShapeType() != TopAbs_FACE) continue;
1401 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1402 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1403 if (exp.Current().IsSame(fdsc)) { // preserved
1409 BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
1410 const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
1411 it2.Initialize(aLM);
1412 for (; it2.More(); it2.Next()) {
1413 const TopoDS_Shape& aS=it2.Value();
1419 myMap.ChangeFind(orig).Clear();
1420 for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1421 // check the appartenance to the shape...
1422 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1423 if (exp.Current().IsSame(itm.Key())) {
1424 // const TopoDS_Shape& sh = itm.Key();
1425 myMap.ChangeFind(orig).Append(itm.Key());
1432 //modified by NIZNHY-PKV Thu Mar 21 18:43:36 2002 t