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>
61 extern Standard_Boolean BRepFeat_GettraceFEAT();
64 static void Descendants(const TopoDS_Shape&,
66 TopTools_MapOfShape&);
68 //=======================================================================
70 //purpose : topological reconstruction of the result
71 //=======================================================================
72 void BRepFeat_Form::GlobalPerform ()
76 Standard_Boolean trc = BRepFeat_GettraceFEAT();
77 if (trc) cout << "BRepFeat_Form::GlobalPerform ()" << endl;
80 if (!mySbOK || !myGSOK || !mySFOK || !mySUOK || !myGFOK ||
83 if (trc) cout << " Fields not initialized in BRepFeat_Form" << endl;
85 myStatusError = BRepFeat_NotInitialized;
91 TopExp_Explorer exp,exp2;
92 Standard_Integer theOpe = 2;
93 TopTools_DataMapIteratorOfDataMapOfShapeShape itm;
95 if(myJustFeat && !myFuse) {
97 if (trc) cout << " Invalid option : myJustFeat + Cut" << endl;
99 myStatusError = BRepFeat_InvOption;
103 else if(myJustFeat) {
106 else if (!myGluedF.IsEmpty()) {
110 Standard_Boolean ChangeOpe = Standard_False;
112 Standard_Boolean FromInShape = Standard_False;
113 Standard_Boolean UntilInShape = Standard_False;
115 if (!mySFrom.IsNull()) {
116 FromInShape = Standard_True;
117 for (exp2.Init(mySFrom,TopAbs_FACE); exp2.More(); exp2.Next()) {
118 const TopoDS_Shape& ffrom = exp2.Current();
119 for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
120 if (exp.Current().IsSame(ffrom)) {
125 FromInShape = Standard_False;
127 if (trc) cout << " From not in Shape" << endl;
134 if (!mySUntil.IsNull()) {
135 UntilInShape = Standard_True;
136 for (exp2.Init(mySUntil,TopAbs_FACE); exp2.More(); exp2.Next()) {
137 const TopoDS_Shape& funtil = exp2.Current();
138 for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
139 if (exp.Current().IsSame(funtil)) {
144 UntilInShape = Standard_False;
146 if (trc) cout << " Until not in Shape" << endl;
153 TopTools_ListIteratorOfListOfShape it,it2;
154 Standard_Integer sens = 0;
156 TColGeom_SequenceOfCurve scur;
159 Standard_Real mf, Mf, mu, Mu;
161 TopAbs_Orientation Orifuntil = TopAbs_INTERNAL;
162 TopAbs_Orientation Oriffrom = TopAbs_INTERNAL;
163 TopoDS_Face FFrom,FUntil;
165 LocOpe_CSIntersector ASI1;
166 LocOpe_CSIntersector ASI2;
168 TopTools_ListOfShape IntList;
171 //--- 1) by intersection
173 // Intersection Tool Shape From
174 if (!mySFrom.IsNull()) {
179 // Intersection Tool Shape Until
180 if (!mySUntil.IsNull()) {
186 // Find sens, FFrom, FUntil
187 for (Standard_Integer jj=1; jj<=scur.Length(); jj++) {
188 if (ASI1.IsDone() && ASI2.IsDone()) {
189 if (ASI1.NbPoints(jj) <= 0) {
192 mf = ASI1.Point(jj,1).Parameter();
193 Mf = ASI1.Point(jj,ASI1.NbPoints(jj)).Parameter();
194 if (ASI2.NbPoints(jj) <= 0) {
197 mu = ASI2.Point(jj,1).Parameter();
198 Mu = ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter();
199 if (!scur(jj)->IsPeriodic()) {
200 Standard_Integer ku, kf;
201 if (! (mu > Mf || mf > Mu)) { //overlapping intervals
204 ku = ASI2.NbPoints(jj);
208 myStatusError = BRepFeat_IntervalOverlap;
214 ku = ASI2.NbPoints(jj);
218 myStatusError = BRepFeat_IntervalOverlap;
223 kf = ASI1.NbPoints(jj);
226 if (Oriffrom == TopAbs_INTERNAL) {
227 TopAbs_Orientation Oript = ASI1.Point(jj,kf).Orientation();
228 if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
230 Oript = TopAbs::Reverse(Oript);
232 Oriffrom = TopAbs::Reverse(Oript);
233 FFrom = ASI1.Point(jj,kf).Face();
236 if (Orifuntil == TopAbs_INTERNAL) {
237 TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
238 if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
240 Oript = TopAbs::Reverse(Oript);
243 FUntil = ASI2.Point(jj,ku).Face();
248 else if (ASI2.IsDone()) {
249 if (ASI2.NbPoints(jj) <= 0)
252 // for base case prism on mySUntil -> ambivalent direction
253 // -> preferrable direction = 1
255 if (ASI2.Point(jj,1).Parameter()*
256 ASI2.Point(jj,ASI2.NbPoints(jj)).Parameter()<=0)
258 else if (ASI2.Point(jj,1).Parameter()<0.)
269 ku = ASI2.NbPoints(jj);
271 if (Orifuntil == TopAbs_INTERNAL && sens != 0) {
272 TopAbs_Orientation Oript = ASI2.Point(jj,ku).Orientation();
273 if (Oript == TopAbs_FORWARD || Oript == TopAbs_REVERSED) {
275 Oript = TopAbs::Reverse(Oript);
278 FUntil = ASI2.Point(jj,ku).Face();
289 LocOpe_Gluer theGlue;
295 if (trc) cout << " Gluer" << endl;
297 Standard_Boolean Collage = Standard_True;
298 // cut by FFrom && FUntil
301 B.MakeCompound(TopoDS::Compound(Comp));
302 if (!mySFrom.IsNull()) {
303 TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
308 if (!mySUntil.IsNull()) {
309 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
315 LocOpe_FindEdges theFE;
316 TopTools_DataMapOfShapeListOfShape locmap;
317 TopExp_Explorer expp(Comp, TopAbs_SOLID);
318 if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
319 BRepAlgoAPI_Cut trP(myGShape, Comp);
320 exp.Init(trP.Shape(), TopAbs_SOLID);
321 if (exp.Current().IsNull()) {
323 ChangeOpe = Standard_True;
324 Collage = Standard_False;
327 // Only solids are preserved
328 TopoDS_Shape theGShape;
329 B.MakeCompound(TopoDS::Compound(theGShape));
330 for (; exp.More(); exp.Next()) {
331 B.Add(theGShape,exp.Current());
333 if (!BRepAlgo::IsValid(theGShape)) {
335 ChangeOpe = Standard_True;
336 Collage = Standard_False;
339 if(!mySFrom.IsNull()) {
341 ex.Init(mySFrom, TopAbs_FACE);
342 for(; ex.More(); ex.Next()) {
343 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
345 TopTools_ListOfShape thelist;
346 myMap.Bind(fac, thelist);
349 TopTools_ListOfShape thelist1;
350 locmap.Bind(fac, thelist1);
352 if (trP.IsDeleted(fac)) {
354 else if (!FromInShape) {
355 myMap(fac) = trP.Modified(fac);
356 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
359 locmap(fac) =trP.Modified(fac) ;
360 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
363 }// if(!mySFrom.IsNull())
365 if(!mySUntil.IsNull()) {
367 ex.Init(mySUntil, TopAbs_FACE);
368 for(; ex.More(); ex.Next()) {
369 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
371 TopTools_ListOfShape thelist2;
372 myMap.Bind(fac,thelist2);
375 TopTools_ListOfShape thelist3;
376 locmap.Bind(fac,thelist3);
378 if (trP.IsDeleted(fac)) {
380 else if (!UntilInShape) {
381 myMap(fac) = trP.Modified(fac);
382 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
385 locmap(fac) = trP.Modified(fac);
386 if (locmap(fac).IsEmpty()) locmap(fac).Append(fac);
389 }// if(!mySUntil.IsNull())
391 UpdateDescendants(trP,theGShape,Standard_True); // skip faces
393 theGlue.Init(mySbase,theGShape);
394 for (itm.Initialize(myGluedF);itm.More();itm.Next()) {
395 const TopoDS_Face& gl = TopoDS::Face(itm.Key());
396 TopTools_ListOfShape ldsc;
397 if (trP.IsDeleted(gl)) {
400 ldsc = trP.Modified(gl);
401 if (ldsc.IsEmpty()) ldsc.Append(gl);
403 const TopoDS_Face& glface = TopoDS::Face(itm.Value());
404 for (it.Initialize(ldsc);it.More();it.Next()) {
405 const TopoDS_Face& fac = TopoDS::Face(it.Value());
406 Collage = BRepFeat::IsInside(fac, glface);
409 ChangeOpe = Standard_True;
413 theGlue.Bind(fac,glface);
414 theFE.Set(fac,glface);
415 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
416 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
423 }// if(expp.More() && !Comp.IsNull() && !myGShape.IsNull())
425 theGlue.Init(mySbase,myGShape);
426 for (itm.Initialize(myGluedF); itm.More();itm.Next()) {
427 const TopoDS_Face& glface = TopoDS::Face(itm.Key());
428 const TopoDS_Face& fac = TopoDS::Face(myGluedF(glface));
429 for (exp.Init(myGShape,TopAbs_FACE); exp.More(); exp.Next()) {
430 if (exp.Current().IsSame(glface)) {
435 Collage = BRepFeat::IsInside(glface, fac);
438 ChangeOpe = Standard_True;
442 theGlue.Bind(glface, fac);
443 theFE.Set(glface, fac);
444 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
445 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
452 // Add gluing on start and end face if necessary !!!
453 if (FromInShape && Collage) {
454 TopExp_Explorer ex(mySFrom,TopAbs_FACE);
455 for(; ex.More(); ex.Next()) {
456 const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
457 // for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
458 for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
459 const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
460 theFE.Set(fac1, fac2);
461 theGlue.Bind(fac1, fac2);
462 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
463 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
466 // myMap.UnBind(fac2);
470 if (UntilInShape && Collage) {
471 TopExp_Explorer ex(mySUntil, TopAbs_FACE);
472 for(; ex.More(); ex.Next()) {
473 const TopoDS_Face& fac2 = TopoDS::Face(ex.Current());
474 // for (it.Initialize(myMap(fac2)); it.More(); it.Next()) {
475 for (it.Initialize(locmap(fac2)); it.More(); it.Next()) {
476 const TopoDS_Face& fac1 = TopoDS::Face(it.Value());
477 theGlue.Bind(fac1, fac2);
478 theFE.Set(fac1, fac2);
479 for (theFE.InitIterator(); theFE.More();theFE.Next()) {
480 theGlue.Bind(theFE.EdgeFrom(),theFE.EdgeTo());
483 //myMap.UnBind(fac2); // to avoid fac2 in Map when
484 // UpdateDescendants(theGlue) is called
488 LocOpe_Operation ope = theGlue.OpeType();
489 if (ope == LocOpe_INVALID ||
490 (myFuse && ope != LocOpe_FUSE) ||
491 (!myFuse && ope != LocOpe_CUT) ||
494 ChangeOpe = Standard_True;
498 //--- if the gluing is always applicable
502 if (trc) cout << " still Gluer" << endl;
505 if (theGlue.IsDone()) {
506 TopoDS_Shape shshs = theGlue.ResultingShape();
507 // if (BRepOffsetAPI::IsTopologicallyValid(shshs)) {
508 if (BRepAlgo::IsValid(shshs)) {
509 UpdateDescendants(theGlue);
510 myNewEdges = theGlue.Edges();
511 myTgtEdges = theGlue.TgtEdges();
513 if (trc) cout << " Gluer result" << endl;
516 myShape = theGlue.ResultingShape();
520 ChangeOpe = Standard_True;
525 ChangeOpe = Standard_True;
530 //--- case without gluing + Tool with proper dimensions
532 if (theOpe == 2 && ChangeOpe && myJustGluer) {
534 if (trc) cout << " Gluer failure" << endl;
536 myJustGluer = Standard_False;
542 //--- case without gluing
546 if (trc) cout << " No Gluer" << endl;
548 TopoDS_Shape theGShape = myGShape;
551 if (trc) cout << " Passage to topological operations" << endl;
557 B.MakeCompound(TopoDS::Compound(Comp));
558 if (!mySFrom.IsNull() || !mySUntil.IsNull()) {
559 if (!mySFrom.IsNull() && !FromInShape) {
560 TopoDS_Solid S = BRepFeat::Tool(mySFrom,FFrom,Oriffrom);
565 if (!mySUntil.IsNull() && !UntilInShape) {
566 if (!mySFrom.IsNull()) {
567 if (!mySFrom.IsSame(mySUntil)) {
568 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
575 TopoDS_Solid S = BRepFeat::Tool(mySUntil,FUntil,Orifuntil);
583 // update type of selection
584 if(myPerfSelection == BRepFeat_SelectionU && !UntilInShape) {
585 myPerfSelection = BRepFeat_NoSelection;
587 else if(myPerfSelection == BRepFeat_SelectionFU &&
588 !FromInShape && !UntilInShape) {
589 myPerfSelection = BRepFeat_NoSelection;
591 else if(myPerfSelection == BRepFeat_SelectionShU && !UntilInShape) {
592 myPerfSelection = BRepFeat_NoSelection;
596 TopExp_Explorer expp(Comp, TopAbs_SOLID);
597 if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
598 BRepAlgoAPI_Cut trP(myGShape, Comp);
599 // the result is necessarily a compound.
600 exp.Init(trP.Shape(),TopAbs_SOLID);
602 myStatusError = BRepFeat_EmptyCutResult;
606 // Only solids are preserved
608 B.MakeCompound(TopoDS::Compound(theGShape));
609 for (; exp.More(); exp.Next()) {
610 B.Add(theGShape,exp.Current());
612 if (!BRepAlgo::IsValid(theGShape)) {
613 myStatusError = BRepFeat_InvShape;
617 if(!mySFrom.IsNull()) {
619 TopExp_Explorer ex(mySFrom, TopAbs_FACE);
620 for(; ex.More(); ex.Next()) {
621 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
622 TopTools_ListOfShape thelist4;
623 myMap.Bind(fac,thelist4);
624 if (trP.IsDeleted(fac)) {
627 myMap(fac) = trP.Modified(fac);
628 if (myMap(fac).IsEmpty()) myMap(fac).Append(fac);
633 if(!mySUntil.IsNull()) {
635 TopExp_Explorer ex(mySUntil, TopAbs_FACE);
636 for(; ex.More(); ex.Next()) {
637 const TopoDS_Face& fac = TopoDS::Face(ex.Current());
638 TopTools_ListOfShape thelist5;
639 myMap.Bind(fac,thelist5);
640 if (trP.IsDeleted(fac)) {
643 myMap(fac) = trP.Modified(fac);
644 if (myMap.IsEmpty()) myMap(fac).Append(fac);
649 UpdateDescendants(trP,theGShape,Standard_True);
650 }//if(expp.More() && !Comp.IsNull() && !myGShape.IsNull()) {
653 //--- generation of "just feature" for assembly = Parts of tool
654 Standard_Boolean bFlag = (myPerfSelection == BRepFeat_NoSelection) ? 0 : 1;
655 BRepFeat_Builder theBuilder;
656 theBuilder.Init(mySbase, theGShape);
657 theBuilder.SetOperation(myFuse, bFlag);
658 theBuilder.Perform();
660 TopTools_ListOfShape lshape;
661 theBuilder.PartsOfTool(lshape);
663 Standard_Real pbmin = RealLast(), pbmax = RealFirst();
664 Standard_Real prmin = RealLast() - 2*Precision::Confusion();
665 Standard_Real prmax = RealFirst() + 2*Precision::Confusion();
666 Standard_Boolean flag1 = Standard_False;
667 Handle(Geom_Curve) C;
669 //--- Selection of pieces of tool to be preserved
670 if(!lshape.IsEmpty() && myPerfSelection != BRepFeat_NoSelection) {
671 // Find ParametricMinMax depending on the constraints of Shape From and Until
672 // -> prmin, prmax, pbmin and pbmax
675 myStatusError = BRepFeat_EmptyBaryCurve;
680 if(myPerfSelection == BRepFeat_SelectionSh) {
681 BRepFeat::ParametricMinMax(mySbase,C,
682 prmin, prmax, pbmin, pbmax, flag1);
684 else if(myPerfSelection == BRepFeat_SelectionFU) {
685 Standard_Real prmin1, prmax1, prmin2, prmax2;
686 Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
688 BRepFeat::ParametricMinMax(mySFrom,C,
689 prmin1, prmax1, prbmin1, prbmax1, flag1);
690 BRepFeat::ParametricMinMax(mySUntil,C,
691 prmin2, prmax2, prbmin2, prbmax2, flag1);
693 // case of revolutions
694 if (C->IsPeriodic()) {
695 Standard_Real period = C->Period();
698 prmin = ElCLib::InPeriod(prmin1,prmax-period,prmax);
701 prmin = Min(prmin1, prmin2);
704 pbmin = ElCLib::InPeriod(prbmin1,pbmax-period,pbmax);
707 prmin = Min(prmin1, prmin2);
708 prmax = Max(prmax1, prmax2);
709 pbmin = Min(prbmin1, prbmin2);
710 pbmax = Max(prbmax1, prbmax2);
713 else if(myPerfSelection == BRepFeat_SelectionShU) {
714 Standard_Real prmin1, prmax1, prmin2, prmax2;
715 Standard_Real prbmin1, prbmax1, prbmin2, prbmax2;
717 if(!myJustFeat && sens == 0) sens =1;
719 myStatusError = BRepFeat_IncDirection;
724 BRepFeat::ParametricMinMax(mySUntil,C,
725 prmin1, prmax1, prbmin1, prbmax1, flag1);
727 BRepFeat::ParametricMinMax(mySbase,C,
728 prmin2, prmax2, prbmin2, prbmax2, flag1);
735 else if (sens == -1) {
742 else if (myPerfSelection == BRepFeat_SelectionU) {
743 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
745 myStatusError = BRepFeat_IncDirection;
750 // Find parts of the tool containing descendants of Shape Until
751 BRepFeat::ParametricMinMax(mySUntil,C,
752 prmin1, prmax1, prbmin1, prbmax1, flag1);
759 else if(sens == -1) {
768 // Finer choice of ParametricMinMax in case when the tool
769 // intersects Shapes From and Until
770 // case of several intersections (keep PartsOfTool according to the selection)
771 // position of the face of intersection in PartsOfTool (before or after)
772 Standard_Real delta = Precision::Confusion();
774 if (myPerfSelection != BRepFeat_NoSelection) {
775 // modif of the test for cts21181 : (prbmax2 and prnmin2) -> (prbmin1 and prbmax1)
776 // correction take into account flag2 for pro15323 and flag3 for pro16060
777 if (!mySUntil.IsNull()) {
778 TopTools_MapOfShape mapFuntil;
779 Descendants(mySUntil,theBuilder,mapFuntil);
780 if (!mapFuntil.IsEmpty()) {
781 for (it.Initialize(lshape); it.More(); it.Next()) {
782 TopExp_Explorer expf;
783 for (expf.Init(it.Value(),TopAbs_FACE);
784 expf.More(); expf.Next()) {
785 if (mapFuntil.Contains(expf.Current())) {
786 Standard_Boolean flag2,flag3;
787 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
788 Standard_Real prmin2, prmax2, prbmin2, prbmax2;
789 BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
790 prbmin1, prbmax1,flag3);
791 BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
792 prbmin2, prbmax2,flag2);
794 Standard_Boolean testOK = !flag2;
797 if (flag1 && prmax2 > prmin + delta) {
799 if (flag3 && prmax1 == prmax2) {
800 testOK = Standard_True;
804 if (prbmin1 < pbmax && testOK) {
812 else if (sens == -1){
813 Standard_Boolean testOK = !flag2;
816 if (flag1 && prmin2 < prmax - delta) {
818 if (flag3 && prmin1 == prmin2) {
819 testOK = Standard_True;
823 if (prbmax1 > pbmin && testOK) {
835 it.Initialize(lshape);
838 if (!mySFrom.IsNull()) {
839 TopTools_MapOfShape mapFfrom;
840 Descendants(mySFrom, theBuilder, mapFfrom);
841 if (!mapFfrom.IsEmpty()) {
842 for (it.Initialize(lshape); it.More(); it.Next()) {
843 TopExp_Explorer expf;
844 for (expf.Init(it.Value(),TopAbs_FACE);
845 expf.More(); expf.Next()) {
846 if (mapFfrom.Contains(expf.Current())) {
847 Standard_Boolean flag2,flag3;
848 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
849 Standard_Real prmin2, prmax2, prbmin2, prbmax2;
850 BRepFeat::ParametricMinMax(expf.Current(),C, prmin1, prmax1,
851 prbmin1, prbmax1,flag3);
852 BRepFeat::ParametricMinMax(it.Value(),C, prmin2, prmax2,
853 prbmin2, prbmax2,flag2);
855 Standard_Boolean testOK = !flag2;
858 if (flag1 && prmin2 < prmax - delta) {
860 if (flag3 && prmin1 == prmin2) {
861 testOK = Standard_True;
865 if (prbmax1 > pbmin && testOK) {
873 else if (sens == -1){
874 Standard_Boolean testOK = !flag2;
877 if (flag1 && prmax2 > prmin + delta) {
879 if (flag3 && prmax1 == prmax2) {
880 testOK = Standard_True;
884 if (prbmin1 < pbmax && testOK) {
896 it.Initialize(lshape);
902 // Parse PartsOfTool to preserve or not depending on ParametricMinMax
904 Standard_Boolean KeepParts = Standard_False;
905 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
906 Standard_Real min, max, pmin, pmax;
907 Standard_Boolean flag2;
908 for (it.Initialize(lshape); it.More(); it.Next()) {
909 if (C->IsPeriodic()) {
910 Standard_Real period = C->Period();
911 Standard_Real pr, prb;
912 BRepFeat::ParametricMinMax(it.Value(),C, pr, prmax1,
913 prb, prbmax1,flag2,Standard_True);
915 prmin1 = ElCLib::InPeriod(pr,prmax1-period,prmax1);
920 prbmin1 = ElCLib::InPeriod(prb,prbmax1-period,prbmax1);
923 BRepFeat::ParametricMinMax(it.Value(),C,
924 prmin1, prmax1, prbmin1, prbmax1,flag2);
926 if(flag2 == Standard_False || flag1 == Standard_False) {
938 if (!((min > pmax - delta) ||
939 (max < pmin + delta))) {
940 KeepParts = Standard_True;
941 const TopoDS_Shape& S = it.Value();
942 theBuilder.KeepPart(S);
946 // Case when no part of the tool is preserved
949 if (trc) cout << " No parts of tool kept" << endl;
951 myStatusError = BRepFeat_NoParts;
957 // case JustFeature -> all PartsOfTool are preserved
958 Standard_Real prmin1, prmax1, prbmin1, prbmax1;
959 Standard_Real min, max, pmin, pmax;
960 Standard_Boolean flag2;
962 B.MakeCompound(TopoDS::Compound(Compo));
963 for (it.Initialize(lshape); it.More(); it.Next()) {
964 BRepFeat::ParametricMinMax(it.Value(),C,
965 prmin1, prmax1, prbmin1, prbmax1,flag2);
966 if(flag2 == Standard_False || flag1 == Standard_False) {
978 if ((min < pmax - delta) &&
979 (max > pmin + delta)){
980 if (!it.Value().IsNull()) {
981 B.Add(Compo,it.Value());
989 //--- Generation of result myShape
992 // removal of edges of section that have no common vertices
993 // with PartsOfTool preserved
995 theBuilder.PerformResult();
996 myShape = theBuilder.Shape();
998 myShape = theBuilder.Shape();
1003 // all is already done
1008 myStatusError = BRepFeat_OK;
1011 //=======================================================================
1012 //function : IsDeleted
1014 //=======================================================================
1016 Standard_Boolean BRepFeat_Form::IsDeleted(const TopoDS_Shape& F)
1018 return (myMap(F).IsEmpty());
1021 //=======================================================================
1022 //function : Modified
1024 //=======================================================================
1026 const TopTools_ListOfShape& BRepFeat_Form::Modified
1027 (const TopoDS_Shape& F)
1029 if (myMap.IsBound(F)) {
1030 static TopTools_ListOfShape list;
1031 list.Clear(); // For the second passage DPF
1032 TopTools_ListIteratorOfListOfShape ite(myMap(F));
1033 for(; ite.More(); ite.Next()) {
1034 const TopoDS_Shape& sh = ite.Value();
1040 return myGenerated; // empty list
1043 //=======================================================================
1044 //function : Generated
1046 //=======================================================================
1048 const TopTools_ListOfShape& BRepFeat_Form::Generated
1049 (const TopoDS_Shape& S)
1051 if (myMap.IsBound(S) &&
1052 S.ShapeType() != TopAbs_FACE) { // check if filter on face or not
1053 static TopTools_ListOfShape list;
1054 list.Clear(); // For the second passage DPF
1055 TopTools_ListIteratorOfListOfShape ite(myMap(S));
1056 for(; ite.More(); ite.Next()) {
1057 const TopoDS_Shape& sh = ite.Value();
1063 else return myGenerated;
1068 //=======================================================================
1069 //function : UpdateDescendants
1071 //=======================================================================
1073 void BRepFeat_Form::UpdateDescendants(const LocOpe_Gluer& G)
1075 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1076 TopTools_ListIteratorOfListOfShape it,it2;
1077 TopTools_MapIteratorOfMapOfShape itm;
1079 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1080 const TopoDS_Shape& orig = itdm.Key();
1081 TopTools_MapOfShape newdsc;
1082 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1083 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1084 for (it2.Initialize(G.DescendantFaces(fdsc));
1085 it2.More();it2.Next()) {
1086 newdsc.Add(it2.Value());
1089 myMap.ChangeFind(orig).Clear();
1090 for (itm.Initialize(newdsc);itm.More();itm.Next()) {
1091 myMap.ChangeFind(orig).Append(itm.Key());
1100 //=======================================================================
1101 //function : FirstShape
1103 //=======================================================================
1105 const TopTools_ListOfShape& BRepFeat_Form::FirstShape() const
1107 if (!myFShape.IsNull()) {
1108 return myMap(myFShape);
1110 return myGenerated; // empty list
1114 //=======================================================================
1115 //function : LastShape
1117 //=======================================================================
1119 const TopTools_ListOfShape& BRepFeat_Form::LastShape() const
1121 if (!myLShape.IsNull()) {
1122 return myMap(myLShape);
1124 return myGenerated; // empty list
1128 //=======================================================================
1129 //function : NewEdges
1131 //=======================================================================
1133 const TopTools_ListOfShape& BRepFeat_Form::NewEdges() const
1139 //=======================================================================
1140 //function : NewEdges
1142 //=======================================================================
1144 const TopTools_ListOfShape& BRepFeat_Form::TgtEdges() const
1150 //=======================================================================
1151 //function : TransformSUntil
1152 //purpose : Limitation of the shape until the case of infinite faces
1153 //=======================================================================
1155 Standard_Boolean BRepFeat_Form::TransformShapeFU(const Standard_Integer flag)
1158 Standard_Boolean trc = BRepFeat_GettraceFEAT();
1160 Standard_Boolean Trf = Standard_False;
1162 TopoDS_Shape shapefu;
1170 TopExp_Explorer exp(shapefu, TopAbs_FACE);
1171 if (!exp.More()) { // no faces... It is necessary to return an error
1173 if (trc) cout << " BRepFeat_Form::TransformShapeFU : invalid Shape" << endl;
1179 if (!exp.More()) { // the only face. Is it infinite?
1181 TopoDS_Face fac = TopoDS::Face(exp.Current());
1183 Handle(Geom_Surface) S = BRep_Tool::Surface(fac);
1184 Handle(Standard_Type) styp = S->DynamicType();
1185 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1186 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
1187 styp = S->DynamicType();
1190 if (styp == STANDARD_TYPE(Geom_Plane) ||
1191 styp == STANDARD_TYPE(Geom_CylindricalSurface) ||
1192 styp == STANDARD_TYPE(Geom_ConicalSurface)) {
1193 TopExp_Explorer exp1(fac, TopAbs_WIRE);
1195 Trf = Standard_True;
1198 Trf = BRep_Tool::NaturalRestriction(fac);
1203 BRepFeat::FaceUntil(mySbase, fac);
1207 TopTools_ListOfShape thelist6;
1208 myMap.Bind(mySFrom,thelist6);
1209 myMap(mySFrom).Append(fac);
1212 else if(flag == 1) {
1213 TopTools_ListOfShape thelist7;
1214 myMap.Bind(mySUntil,thelist7);
1215 myMap(mySUntil).Append(fac);
1222 for (exp.ReInit(); exp.More(); exp.Next()) {
1223 const TopoDS_Shape& fac = exp.Current();
1224 TopTools_ListOfShape thelist8;
1225 myMap.Bind(fac,thelist8);
1226 myMap(fac).Append(fac);
1231 if (Trf && (flag == 0)) cout << " TransformShapeFU From" << endl;
1232 if (Trf && (flag == 1)) cout << " TransformShapeFU Until" << endl;
1239 //=======================================================================
1240 //function : CurrentStatusError
1242 //=======================================================================
1244 BRepFeat_StatusError BRepFeat_Form::CurrentStatusError() const
1246 return myStatusError;
1249 //=======================================================================
1250 //function : Descendants
1252 //=======================================================================
1254 static void Descendants(const TopoDS_Shape& S,
1255 BRepFeat_Builder& theFB,
1256 TopTools_MapOfShape& mapF)
1259 TopTools_ListIteratorOfListOfShape it;
1260 TopExp_Explorer exp;
1261 for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
1263 const TopoDS_Face& fdsc = TopoDS::Face(exp.Current());
1264 const TopTools_ListOfShape& aLM=theFB.Modified(fdsc);
1266 for (; it.More(); it.Next()) {
1267 mapF.Add(it.Value());
1273 //=======================================================================
1274 //function : UpdateDescendants
1276 //=======================================================================
1277 void BRepFeat_Form::UpdateDescendants(const Handle(TopOpeBRepBuild_HBuilder)& B,
1278 const TopoDS_Shape& S,
1279 const Standard_Boolean SkipFace)
1281 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1282 TopTools_ListIteratorOfListOfShape it,it2;
1283 TopTools_MapIteratorOfMapOfShape itm;
1284 TopExp_Explorer exp;
1286 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1287 const TopoDS_Shape& orig = itdm.Key();
1288 if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1291 TopTools_MapOfShape newdsc;
1293 if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1295 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1296 const TopoDS_Shape& sh = it.Value();
1297 if(sh.ShapeType() != TopAbs_FACE) continue;
1298 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1299 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1300 if (exp.Current().IsSame(fdsc)) { // preserved
1306 if (B->IsSplit(fdsc, TopAbs_OUT)) {
1307 for (it2.Initialize(B->Splits(fdsc,TopAbs_OUT));
1308 it2.More();it2.Next()) {
1309 newdsc.Add(it2.Value());
1312 if (B->IsSplit(fdsc, TopAbs_IN)) {
1313 for (it2.Initialize(B->Splits(fdsc,TopAbs_IN));
1314 it2.More();it2.Next()) {
1315 newdsc.Add(it2.Value());
1318 if (B->IsSplit(fdsc, TopAbs_ON)) {
1319 for (it2.Initialize(B->Splits(fdsc,TopAbs_ON));
1320 it2.More();it2.Next()) {
1321 newdsc.Add(it2.Value());
1324 if (B->IsMerged(fdsc, TopAbs_OUT)) {
1325 for (it2.Initialize(B->Merged(fdsc,TopAbs_OUT));
1326 it2.More();it2.Next()) {
1327 newdsc.Add(it2.Value());
1330 if (B->IsMerged(fdsc, TopAbs_IN)) {
1331 for (it2.Initialize(B->Merged(fdsc,TopAbs_IN));
1332 it2.More();it2.Next()) {
1333 newdsc.Add(it2.Value());
1336 if (B->IsMerged(fdsc, TopAbs_ON)) {
1337 for (it2.Initialize(B->Merged(fdsc,TopAbs_ON));
1338 it2.More();it2.Next()) {
1339 newdsc.Add(it2.Value());
1344 myMap.ChangeFind(orig).Clear();
1345 for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1346 // check the appartenance to the shape...
1347 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1348 if (exp.Current().IsSame(itm.Key())) {
1349 // const TopoDS_Shape& sh = itm.Key();
1350 myMap.ChangeFind(orig).Append(itm.Key());
1357 //=======================================================================
1358 //function : UpdateDescendants
1360 //=======================================================================
1361 void BRepFeat_Form::UpdateDescendants(const BRepAlgoAPI_BooleanOperation& aBOP,
1362 const TopoDS_Shape& S,
1363 const Standard_Boolean SkipFace)
1365 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm;
1366 TopTools_ListIteratorOfListOfShape it,it2;
1367 TopTools_MapIteratorOfMapOfShape itm;
1368 TopExp_Explorer exp;
1370 for (itdm.Initialize(myMap);itdm.More();itdm.Next()) {
1371 const TopoDS_Shape& orig = itdm.Key();
1372 if (SkipFace && orig.ShapeType() == TopAbs_FACE) {
1375 TopTools_MapOfShape newdsc;
1377 if (itdm.Value().IsEmpty()) {myMap.ChangeFind(orig).Append(orig);}
1379 for (it.Initialize(itdm.Value());it.More();it.Next()) {
1380 const TopoDS_Shape& sh = it.Value();
1381 if(sh.ShapeType() != TopAbs_FACE) continue;
1382 const TopoDS_Face& fdsc = TopoDS::Face(it.Value());
1383 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1384 if (exp.Current().IsSame(fdsc)) { // preserved
1390 BRepAlgoAPI_BooleanOperation* pBOP=(BRepAlgoAPI_BooleanOperation*)&aBOP;
1391 const TopTools_ListOfShape& aLM=pBOP->Modified(fdsc);
1392 it2.Initialize(aLM);
1393 for (; it2.More(); it2.Next()) {
1394 const TopoDS_Shape& aS=it2.Value();
1400 myMap.ChangeFind(orig).Clear();
1401 for (itm.Initialize(newdsc); itm.More(); itm.Next()) {
1402 // check the appartenance to the shape...
1403 for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1404 if (exp.Current().IsSame(itm.Key())) {
1405 // const TopoDS_Shape& sh = itm.Key();
1406 myMap.ChangeFind(orig).Append(itm.Key());