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;
337 B.MakeCompound(TopoDS::Compound(theGShape));
338 for (; exp.More(); exp.Next()) {
339 B.Add(theGShape,exp.Current());
341 if (!BRepAlgo::IsValid(theGShape)) {
343 ChangeOpe = Standard_True;
344 Collage = Standard_False;
347 if(!mySFrom.IsNull()) {
349 ex.Init(mySFrom, TopAbs_FACE);
350 for(; ex.More(); ex.Next()) {
351 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
353 TopTools_ListOfShape thelist;
354 myMap.Bind(fac, thelist);
357 TopTools_ListOfShape thelist1;
358 locmap.Bind(fac, thelist1);
360 if (trP.IsDeleted(fac)) {
362 else if (!FromInShape) {
363 myMap(fac) = trP.Modified(fac);
364 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
367 locmap(fac) =trP.Modified(fac) ;
368 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
371 }// if(!mySFrom.IsNull())
373 if(!mySUntil.IsNull()) {
375 ex.Init(mySUntil, TopAbs_FACE);
376 for(; ex.More(); ex.Next()) {
377 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
379 TopTools_ListOfShape thelist2;
380 myMap.Bind(fac,thelist2);
383 TopTools_ListOfShape thelist3;
384 locmap.Bind(fac,thelist3);
386 if (trP.IsDeleted(fac)) {
388 else if (!UntilInShape) {
389 myMap(fac) = trP.Modified(fac);
390 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
393 locmap(fac) = trP.Modified(fac);
394 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
397 }// if(!mySUntil.IsNull())
399 //modified by NIZNHY-PKV Thu Mar 21 17:21:49 2002 f
400 //UpdateDescendants(trP.Builder(),theGShape,Standard_True); // skip faces
401 UpdateDescendants(trP,theGShape,Standard_True); // skip faces
402 //modified by NIZNHY-PKV Thu Mar 21 17:22:32 2002 t
404 theGlue.Init(mySbase,theGShape);
405 for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
406 const TopoDS_Face& gl = TopoDS::Face(itm.Key());
407 TopTools_ListOfShape ldsc;
408 if (trP.IsDeleted(gl)) {
411 ldsc = trP.Modified(gl);
412 if (ldsc.IsEmpty()) ldsc.Append(gl);
414 const TopoDS_Face& glface = TopoDS::Face(itm.Value());
415 for (it.Initialize(ldsc);it.More();it.Next()) {
416 const TopoDS_Face& fac = TopoDS::Face(it.Value());
417 Collage = BRepFeat::IsInside(fac, glface);
420 ChangeOpe = Standard_True;
424 theGlue.Bind(fac,glface);
425 theFE.Set(fac,glface);
426 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
427 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
434 }// if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())
436 theGlue.Init(mySbase,myGShape);
437 for (itm.Initialize(myGluedF); itm.More();itm.Next()) {
438 const TopoDS_Face& glface = TopoDS::Face(itm.Key());
439 const TopoDS_Face& fac = TopoDS::Face(myGluedF(glface));
440 for (exp.Init(myGShape,TopAbs_FACE); exp.More(); exp.Next()) {
441 if (exp.Current().IsSame(glface)) {
446 Collage = BRepFeat::IsInside(glface, fac);
449 ChangeOpe = Standard_True;
453 theGlue.Bind(glface, fac);
454 theFE.Set(glface, fac);
455 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
456 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
463 // Add gluing on start and end face if necessary !!!
464 if (FromInShape && Collage) {
465 TopExp_Explorer ex(mySFrom,TopAbs_FACE);
466 for(; ex.More(); ex.Next()) {
467 const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
468 // for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
469 for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
470 const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
471 theFE.Set(fac1, fac2);
472 theGlue.Bind(fac1, fac2);
473 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
474 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
477 // myMap.UnBind(fac2);
481 if (UntilInShape && Collage) {
482 TopExp_Explorer ex(mySUntil, TopAbs_FACE);
483 for(; ex.More(); ex.Next()) {
484 const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
485 // for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
486 for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
487 const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
488 theGlue.Bind(fac1, fac2);
489 theFE.Set(fac1, fac2);
490 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
491 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
494 //myMap.UnBind(fac2); // to avoid fac2 in Map when
495 // UpdateDescendants(theGlue) is called
499 LocOpe_Operation ope = theGlue.OpeType();
500 if (ope == LocOpe_INVALID ||
501 (myFuse && ope != LocOpe_FUSE) ||
502 (!myFuse && ope != LocOpe_CUT) ||
505 ChangeOpe = Standard_True;
509 //--- if the gluing is always applicable
513 if (trc) cout << " still Gluer" << endl;
516 if (theGlue.IsDone()) {
517 TopoDS_Shape shshs = theGlue.ResultingShape();
518 // if (BRepOffsetAPI::IsTopologicallyValid(shshs)) {
519 if (BRepAlgo::IsValid(shshs)) {
520 UpdateDescendants(theGlue);
521 myNewEdges = theGlue.Edges();
522 myTgtEdges = theGlue.TgtEdges();
524 if (trc) cout << " Gluer result" << endl;
527 myShape = theGlue.ResultingShape();
531 ChangeOpe = Standard_True;
536 ChangeOpe = Standard_True;
541 //--- case without gluing + Tool with proper dimensions
543 if (theOpe == 2 && ChangeOpe && myJustGluer) {
545 if (trc) cout << " Gluer failure" << endl;
547 myJustGluer = Standard_False;
553 //--- case without gluing
557 if (trc) cout << " No Gluer" << endl;
559 TopoDS_Shape theGShape = myGShape;
562 if (trc) cout << " Passage to topological operations" << endl;
568 B.MakeCompound(TopoDS::Compound(Comp));
569 if (!mySFrom.IsNull() || !mySUntil.IsNull()) {
570 if (!mySFrom.IsNull() && !FromInShape) {
571 TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
576 if (!mySUntil.IsNull() && !UntilInShape) {
577 if (!mySFrom.IsNull()) {
578 if (!mySFrom.IsSame(mySUntil)) {
579 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
586 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
594 // update type of selection
595 if(myPerfSelection == BRepFeat_SelectionU && !UntilInShape) {
596 myPerfSelection = BRepFeat_NoSelection;
598 else if(myPerfSelection == BRepFeat_SelectionFU &&
599 !FromInShape && !UntilInShape) {
600 myPerfSelection = BRepFeat_NoSelection;
602 else if(myPerfSelection == BRepFeat_SelectionShU && !UntilInShape) {
603 myPerfSelection = BRepFeat_NoSelection;
607 TopExp_Explorer expp(Comp, TopAbs_SOLID);
608 if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
609 //modified by NIZNHY-PKV Thu Mar 21 17:24:52 2002 f
610 //BRepAlgo_Cut trP(myGShape,Comp);
611 BRepAlgoAPI_Cut trP(myGShape, Comp);
612 //modified by NIZNHY-PKV Thu Mar 21 17:24:56 2002 t
613 // the result is necessarily a compound.
614 exp.Init(trP.Shape(),TopAbs_SOLID);
616 myStatusError = BRepFeat_EmptyCutResult;
620 // Only solids are preserved
623 B.MakeCompound(TopoDS::Compound(theGShape));
624 for (; exp.More(); exp.Next()) {
625 B.Add(theGShape,exp.Current());
627 if (!BRepAlgo::IsValid(theGShape)) {
628 myStatusError = BRepFeat_InvShape;
632 if(!mySFrom.IsNull()) {
634 TopExp_Explorer ex(mySFrom, TopAbs_FACE);
635 for(; ex.More(); ex.Next()) {
636 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
637 TopTools_ListOfShape thelist4;
638 myMap.Bind(fac,thelist4);
639 if (trP.IsDeleted(fac)) {
642 myMap(fac) = trP.Modified(fac);
643 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
648 if(!mySUntil.IsNull()) {
650 TopExp_Explorer ex(mySUntil, TopAbs_FACE);
651 for(; ex.More(); ex.Next()) {
652 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
653 TopTools_ListOfShape thelist5;
654 myMap.Bind(fac,thelist5);
655 if (trP.IsDeleted(fac)) {
658 myMap(fac) = trP.Modified(fac);
659 if (myMap.IsEmpty()) myMap(fac).Append(fac);
664 //modified by NIZNHY-PKV Thu Mar 21 17:27:23 2002 f
665 //UpdateDescendants(trP.Builder(),theGShape,Standard_True);
666 UpdateDescendants(trP,theGShape,Standard_True);
667 //modified by NIZNHY-PKV Thu Mar 21 17:27:31 2002 t
668 }//if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
671 //--- generation of "just feature" for assembly = Parts of tool
672 Standard_Boolean bFlag = (myPerfSelection == BRepFeat_NoSelection) ? 0 : 1;
673 BRepFeat_Builder theBuilder;
674 theBuilder.Init(mySbase, theGShape);
675 theBuilder.SetOperation(myFuse, bFlag);
676 theBuilder.Perform();
678 TopTools_ListOfShape lshape;
679 theBuilder.PartsOfTool(lshape);
681 Standard_Real pbmin = RealLast(), pbmax = RealFirst();
682 Standard_Real prmin = RealLast() - 2*Precision::Confusion();
683 Standard_Real prmax = RealFirst() + 2*Precision::Confusion();
684 Standard_Boolean flag1 = Standard_False;
685 Handle(Geom_Curve) C;
687 //--- Selection of pieces of tool to be preserved
688 if(!lshape.IsEmpty() && myPerfSelection != BRepFeat_NoSelection) {
689 // Find ParametricMinMax depending on the constraints of Shape From and Until
690 // -> prmin, prmax, pbmin and pbmax
693 myStatusError = BRepFeat_EmptyBaryCurve;
698 if(myPerfSelection == BRepFeat_SelectionSh) {
699 BRepFeat::ParametricMinMax(mySbase,C,
700 prmin, prmax, pbmin, pbmax, flag1);
702 else if(myPerfSelection == BRepFeat_SelectionFU) {
703 Standard_Real prmin1, prmax1, prmin2, prmax2;
704 Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
706 BRepFeat::ParametricMinMax(mySFrom,C,
707 prmin1, prmax1, prbmin1, prbmax1, flag1);
708 BRepFeat::ParametricMinMax(mySUntil,C,
709 prmin2, prmax2, prbmin2, prbmax2, flag1);
711 // case of revolutions
712 if (C->IsPeriodic()) {
713 Standard_Real period = C->Period();
716 prmin = ElCLib::InPeriod(prmin1,prmax-period,prmax);
719 prmin = Min(prmin1, prmin2);
722 pbmin = ElCLib::InPeriod(prbmin1,pbmax-period,pbmax);
725 prmin = Min(prmin1, prmin2);
726 prmax = Max(prmax1, prmax2);
727 pbmin = Min(prbmin1, prbmin2);
728 pbmax = Max(prbmax1, prbmax2);
731 else if(myPerfSelection == BRepFeat_SelectionShU) {
732 Standard_Real prmin1, prmax1, prmin2, prmax2;
733 Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
735 if(!myJustFeat && sens == 0) sens =1;
737 myStatusError = BRepFeat_IncDirection;
742 BRepFeat::ParametricMinMax(mySUntil,C,
743 prmin1, prmax1, prbmin1, prbmax1, flag1);
745 BRepFeat::ParametricMinMax(mySbase,C,
746 prmin2, prmax2, prbmin2, prbmax2, flag1);
753 else if (sens == -1) {
760 else if (myPerfSelection == BRepFeat_SelectionU) {
761 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
763 myStatusError = BRepFeat_IncDirection;
768 // Find parts of the tool containing descendants of Shape Until
769 BRepFeat::ParametricMinMax(mySUntil,C,
770 prmin1, prmax1, prbmin1, prbmax1, flag1);
777 else if(sens == -1) {
786 // Finer choice of ParametricMinMax in case when the tool
787 // intersects Shapes From and Until
788 // case of several intersections (keep PartsOfTool according to the selection)
789 // position of the face of intersection in PartsOfTool (before or after)
790 Standard_Real delta = Precision::Confusion();
792 if (myPerfSelection != BRepFeat_NoSelection) {
793 // modif of the test for cts21181 : (prbmax2 and prnmin2) -> (prbmin1 and prbmax1)
794 // correction take into account flag2 for pro15323 and flag3 for pro16060
795 if (!mySUntil.IsNull()) {
796 TopTools_MapOfShape mapFuntil;
797 Descendants(mySUntil,theBuilder,mapFuntil);
798 if (!mapFuntil.IsEmpty()) {
799 for (it.Initialize(lshape); it.More(); it.Next()) {
800 TopExp_Explorer expf;
801 for (expf.Init(it.Value(),TopAbs_FACE);
802 expf.More(); expf.Next()) {
803 if (mapFuntil.Contains(expf.Current())) {
804 Standard_Boolean flag2,flag3;
805 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
806 Standard_Real prmin2, prmax2, prbmin2, prbmax2;
807 BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
808 prbmin1, prbmax1,flag3);
809 BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
810 prbmin2, prbmax2,flag2);
812 Standard_Boolean testOK = !flag2;
815 if (flag1 && prmax2 > prmin + delta) {
817 if (flag3 && prmax1 == prmax2) {
818 testOK = Standard_True;
822 if (prbmin1 < pbmax && testOK) {
830 else if (sens == -1){
831 Standard_Boolean testOK = !flag2;
834 if (flag1 && prmin2 < prmax - delta) {
836 if (flag3 && prmin1 == prmin2) {
837 testOK = Standard_True;
841 if (prbmax1 > pbmin && testOK) {
853 it.Initialize(lshape);
856 if (!mySFrom.IsNull()) {
857 TopTools_MapOfShape mapFfrom;
858 Descendants(mySFrom, theBuilder, mapFfrom);
859 if (!mapFfrom.IsEmpty()) {
860 for (it.Initialize(lshape); it.More(); it.Next()) {
861 TopExp_Explorer expf;
862 for (expf.Init(it.Value(),TopAbs_FACE);
863 expf.More(); expf.Next()) {
864 if (mapFfrom.Contains(expf.Current())) {
865 Standard_Boolean flag2,flag3;
866 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
867 Standard_Real prmin2, prmax2, prbmin2, prbmax2;
868 BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
869 prbmin1, prbmax1,flag3);
870 BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
871 prbmin2, prbmax2,flag2);
873 Standard_Boolean testOK = !flag2;
876 if (flag1 && prmin2 < prmax - delta) {
878 if (flag3 && prmin1 == prmin2) {
879 testOK = Standard_True;
883 if (prbmax1 > pbmin && testOK) {
891 else if (sens == -1){
892 Standard_Boolean testOK = !flag2;
895 if (flag1 && prmax2 > prmin + delta) {
897 if (flag3 && prmax1 == prmax2) {
898 testOK = Standard_True;
902 if (prbmin1 < pbmax && testOK) {
914 it.Initialize(lshape);
920 // Parse PartsOfTool to preserve or not depending on ParametricMinMax
922 Standard_Boolean KeepParts = Standard_False;
923 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
924 Standard_Real min, max, pmin, pmax;
925 Standard_Boolean flag2;
926 for (it.Initialize(lshape); it.More(); it.Next()) {
927 if (C->IsPeriodic()) {
928 Standard_Real period = C->Period();
929 Standard_Real pr, prb;
930 BRepFeat::ParametricMinMax(it.Value(),C, pr, prmax1,
931 prb, prbmax1,flag2,Standard_True);
933 prmin1 = ElCLib::InPeriod(pr,prmax1-period,prmax1);
938 prbmin1 = ElCLib::InPeriod(prb,prbmax1-period,prbmax1);
941 BRepFeat::ParametricMinMax(it.Value(),C,
942 prmin1, prmax1, prbmin1, prbmax1,flag2);
944 if(flag2 == Standard_False || flag1 == Standard_False) {
956 if (!((min > pmax - delta) ||
957 (max < pmin + delta))) {
958 KeepParts = Standard_True;
959 const TopoDS_Shape& S = it.Value();
960 theBuilder.KeepPart(S);
964 // Case when no part of the tool is preserved
967 if (trc) cout << " No parts of tool kept" << endl;
969 myStatusError = BRepFeat_NoParts;
975 // case JustFeature -> all PartsOfTool are preserved
976 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
977 Standard_Real min, max, pmin, pmax;
978 Standard_Boolean flag2;
981 B.MakeCompound(TopoDS::Compound(Compo));
982 for (it.Initialize(lshape); it.More(); it.Next()) {
983 BRepFeat::ParametricMinMax(it.Value(),C,
984 prmin1, prmax1, prbmin1, prbmax1,flag2);
985 if(flag2 == Standard_False || flag1 == Standard_False) {
997 if ((min < pmax - delta) &&
998 (max > pmin + delta)){
999 if (!it.Value().IsNull()) {
1000 B.Add(Compo,it.Value());
1008 //--- Generation of result myShape
1011 // removal of edges of section that have no common vertices
1012 // with PartsOfTool preserved
1013 //modified by NIZHNY-EMV Thu May 10 15:56:24 2012
1015 theBuilder.PerformResult();
1016 myShape = theBuilder.Shape();
1018 myShape = theBuilder.Shape();
1020 //modified by NIZHNY-EMV Thu May 10 15:56:26 2012
1024 // all is already done
1029 myStatusError = BRepFeat_OK;
1032 //=======================================================================
1033 //function : IsDeleted
1035 //=======================================================================
1037 Standard_Boolean BRepFeat_Form::IsDeleted(const TopoDS_Shape& F)
1039 return (myMap(F).IsEmpty());
1042 //=======================================================================
1043 //function : Modified
1045 //=======================================================================
1047 const TopTools_ListOfShape& BRepFeat_Form::Modified
1048 (const TopoDS_Shape& F)
1050 if (myMap.IsBound(F)) {
1051 static TopTools_ListOfShape list;
1052 list.Clear(); // For the second passage DPF
1053 TopTools_ListIteratorOfListOfShape ite(myMap(F));
1054 for(; ite.More(); ite.Next()) {
1055 const TopoDS_Shape& sh = ite.Value();
1061 return myGenerated; // empty list
1064 //=======================================================================
1065 //function : Generated
1067 //=======================================================================
1069 const TopTools_ListOfShape& BRepFeat_Form::Generated
1070 (const TopoDS_Shape& S)
1072 if (myMap.IsBound(S) &&
1073 S.ShapeType() != TopAbs_FACE) { // check if filter on face or not
1074 static TopTools_ListOfShape list;
1075 list.Clear(); // For the second passage DPF
1076 TopTools_ListIteratorOfListOfShape ite(myMap(S));
1077 for(; ite.More(); ite.Next()) {
1078 const TopoDS_Shape& sh = ite.Value();
1084 else return myGenerated;
1089 //=======================================================================
1090 //function : UpdateDescendants
1092 //=======================================================================
1094 void BRepFeat_Form::UpdateDescendants(const LocOpe_Gluer& G)
1096 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1097 TopTools_ListIteratorOfListOfShape it,it2;
1098 TopTools_MapIteratorOfMapOfShape itm;
1100 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1101 const TopoDS_Shape& orig = itdm.Key();
1102 TopTools_MapOfShape newdsc;
1103 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1104 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1105 for (it2.Initialize(G.DescendantFaces(fdsc));
1106 it2.More();it2.Next()) {
1107 newdsc.Add(it2.Value());
1110 myMap.ChangeFind(orig).Clear();
1111 for (itm.Initialize(newdsc);itm.More();itm.Next()) {
1112 myMap.ChangeFind(orig).Append(itm.Key());
1121 //=======================================================================
1122 //function : FirstShape
1124 //=======================================================================
1126 const TopTools_ListOfShape& BRepFeat_Form::FirstShape() const
1128 if (!myFShape.IsNull()) {
1129 return myMap(myFShape);
1131 return myGenerated; // empty list
1135 //=======================================================================
1136 //function : LastShape
1138 //=======================================================================
1140 const TopTools_ListOfShape& BRepFeat_Form::LastShape() const
1142 if (!myLShape.IsNull()) {
1143 return myMap(myLShape);
1145 return myGenerated; // empty list
1149 //=======================================================================
1150 //function : NewEdges
1152 //=======================================================================
1154 const TopTools_ListOfShape& BRepFeat_Form::NewEdges() const
1160 //=======================================================================
1161 //function : NewEdges
1163 //=======================================================================
1165 const TopTools_ListOfShape& BRepFeat_Form::TgtEdges() const
1171 //=======================================================================
1172 //function : TransformSUntil
1173 //purpose : Limitation of the shape until the case of infinite faces
1174 //=======================================================================
1176 Standard_Boolean BRepFeat_Form::TransformShapeFU(const Standard_Integer flag)
1179 Standard_Boolean trc = BRepFeat_GettraceFEAT();
1181 Standard_Boolean Trf = Standard_False;
1183 TopoDS_Shape shapefu;
1191 TopExp_Explorer exp(shapefu, TopAbs_FACE);
1192 if (!exp.More()) { // no faces... It is necessary to return an error
1194 if (trc) cout << " BRepFeat_Form::TransformShapeFU : invalid Shape" << endl;
1200 if (!exp.More()) { // the only face. Is it infinite?
1202 TopoDS_Face fac = TopoDS::Face(exp.Current());
1204 Handle(Geom_Surface) S = BRep_Tool::Surface(fac);
1205 Handle(Standard_Type) styp = S->DynamicType();
1206 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1207 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
1208 styp = S->DynamicType();
1211 if (styp == STANDARD_TYPE(Geom_Plane) ||
1212 styp == STANDARD_TYPE(Geom_CylindricalSurface) ||
1213 styp == STANDARD_TYPE(Geom_ConicalSurface)) {
1214 TopExp_Explorer exp1(fac, TopAbs_WIRE);
1216 Trf = Standard_True;
1219 Trf = BRep_Tool::NaturalRestriction(fac);
1224 BRepFeat::FaceUntil(mySbase, fac);
1228 TopTools_ListOfShape thelist6;
1229 myMap.Bind(mySFrom,thelist6);
1230 myMap(mySFrom).Append(fac);
1233 else if(flag == 1) {
1234 TopTools_ListOfShape thelist7;
1235 myMap.Bind(mySUntil,thelist7);
1236 myMap(mySUntil).Append(fac);
1243 for (exp.ReInit(); exp.More(); exp.Next()) {
1244 const TopoDS_Shape& fac = exp.Current();
1245 TopTools_ListOfShape thelist8;
1246 myMap.Bind(fac,thelist8);
1247 myMap(fac).Append(fac);
1252 if (Trf && (flag == 0)) cout << " TransformShapeFU From" << endl;
1253 if (Trf && (flag == 1)) cout << " TransformShapeFU Until" << endl;
1260 //=======================================================================
1261 //function : CurrentStatusError
1263 //=======================================================================
1265 BRepFeat_StatusError BRepFeat_Form::CurrentStatusError() const
1267 return myStatusError;
1270 //=======================================================================
1271 //function : Descendants
1273 //=======================================================================
1275 static void Descendants(const TopoDS_Shape& S,
1276 BRepFeat_Builder& theFB,
1277 TopTools_MapOfShape& mapF)
1280 TopTools_ListIteratorOfListOfShape it;
1281 TopExp_Explorer exp;
1282 for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1284 const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1285 const TopTools_ListOfShape& aLM=theFB.Modified(fdsc);
1287 for (; it.More(); it.Next()) {
1288 mapF.Add(it.Value());
1294 //=======================================================================
1295 //function : UpdateDescendants
1297 //=======================================================================
1298 void BRepFeat_Form::UpdateDescendants(const Handle(TopOpeBRepBuild_HBuilder)& B,
1299 const TopoDS_Shape& S,
1300 const Standard_Boolean SkipFace)
1302 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1303 TopTools_ListIteratorOfListOfShape it,it2;
1304 TopTools_MapIteratorOfMapOfShape itm;
1305 TopExp_Explorer exp;
1307 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1308 const TopoDS_Shape& orig = itdm.Key();
1309 if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1312 TopTools_MapOfShape newdsc;
1314 if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1316 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1317 const TopoDS_Shape& sh = it.Value();
1318 if(sh.ShapeType() != TopAbs_FACE) continue;
1319 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1320 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1321 if (exp.Current().IsSame(fdsc)) { // preserved
1327 if (B->IsSplit(fdsc, TopAbs_OUT)) {
1328 for (it2.Initialize(B->Splits(fdsc,TopAbs_OUT));
1329 it2.More();it2.Next()) {
1330 newdsc.Add(it2.Value());
1333 if (B->IsSplit(fdsc, TopAbs_IN)) {
1334 for (it2.Initialize(B->Splits(fdsc,TopAbs_IN));
1335 it2.More();it2.Next()) {
1336 newdsc.Add(it2.Value());
1339 if (B->IsSplit(fdsc, TopAbs_ON)) {
1340 for (it2.Initialize(B->Splits(fdsc,TopAbs_ON));
1341 it2.More();it2.Next()) {
1342 newdsc.Add(it2.Value());
1345 if (B->IsMerged(fdsc, TopAbs_OUT)) {
1346 for (it2.Initialize(B->Merged(fdsc,TopAbs_OUT));
1347 it2.More();it2.Next()) {
1348 newdsc.Add(it2.Value());
1351 if (B->IsMerged(fdsc, TopAbs_IN)) {
1352 for (it2.Initialize(B->Merged(fdsc,TopAbs_IN));
1353 it2.More();it2.Next()) {
1354 newdsc.Add(it2.Value());
1357 if (B->IsMerged(fdsc, TopAbs_ON)) {
1358 for (it2.Initialize(B->Merged(fdsc,TopAbs_ON));
1359 it2.More();it2.Next()) {
1360 newdsc.Add(it2.Value());
1365 myMap.ChangeFind(orig).Clear();
1366 for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1367 // check the appartenance to the shape...
1368 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1369 if (exp.Current().IsSame(itm.Key())) {
1370 // const TopoDS_Shape& sh = itm.Key();
1371 myMap.ChangeFind(orig).Append(itm.Key());
1378 //modified by NIZNHY-PKV Thu Mar 21 18:43:18 2002 f
1379 //=======================================================================
1380 //function : UpdateDescendants
1382 //=======================================================================
1383 void BRepFeat_Form::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
1384 const TopoDS_Shape& S,
1385 const Standard_Boolean SkipFace)
1387 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1388 TopTools_ListIteratorOfListOfShape it,it2;
1389 TopTools_MapIteratorOfMapOfShape itm;
1390 TopExp_Explorer exp;
1392 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1393 const TopoDS_Shape& orig = itdm.Key();
1394 if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1397 TopTools_MapOfShape newdsc;
1399 if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1401 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1402 const TopoDS_Shape& sh = it.Value();
1403 if(sh.ShapeType() != TopAbs_FACE) continue;
1404 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1405 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1406 if (exp.Current().IsSame(fdsc)) { // preserved
1412 BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
1413 const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
1414 it2.Initialize(aLM);
1415 for (; it2.More(); it2.Next()) {
1416 const TopoDS_Shape& aS=it2.Value();
1422 myMap.ChangeFind(orig).Clear();
1423 for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1424 // check the appartenance to the shape...
1425 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1426 if (exp.Current().IsSame(itm.Key())) {
1427 // const TopoDS_Shape& sh = itm.Key();
1428 myMap.ChangeFind(orig).Append(itm.Key());
1435 //modified by NIZNHY-PKV Thu Mar 21 18:43:36 2002 t