1 // Created on: 1997-04-14
2 // Created by: Olga KOULECHOVA
3 // Copyright (c) 1997-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 <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAlgoAPI_Common.hxx>
21 #include <BRepAlgoAPI_Section.hxx>
22 #include <BRepBuilderAPI.hxx>
23 #include <BRepBuilderAPI_MakeFace.hxx>
24 #include <BRepBuilderAPI_Transform.hxx>
25 #include <BRepExtrema_ExtCF.hxx>
26 #include <BRepExtrema_ExtPC.hxx>
27 #include <BRepExtrema_ExtPF.hxx>
28 #include <BRepFeat.hxx>
29 #include <BRepFeat_MakeLinearForm.hxx>
30 #include <BRepLib_MakeEdge.hxx>
31 #include <BRepLib_MakeFace.hxx>
32 #include <BRepLib_MakeVertex.hxx>
33 #include <BRepLib_MakeWire.hxx>
34 #include <BRepPrimAPI_MakeBox.hxx>
35 #include <BRepTools.hxx>
36 #include <BRepTools_Modifier.hxx>
37 #include <BRepTools_TrsfModification.hxx>
38 #include <BRepTools_WireExplorer.hxx>
39 #include <Geom2d_Curve.hxx>
40 #include <Geom2d_Line.hxx>
41 #include <Geom_Curve.hxx>
42 #include <Geom_CylindricalSurface.hxx>
43 #include <Geom_Plane.hxx>
44 #include <Geom_RectangularTrimmedSurface.hxx>
45 #include <Geom_Surface.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47 #include <GeomLProp_CLProps.hxx>
48 #include <GeomProjLib.hxx>
53 #include <gp_Pnt2d.hxx>
55 #include <gp_Vec2d.hxx>
56 #include <IntRes2d_IntersectionPoint.hxx>
58 #include <LocOpe_FindEdges.hxx>
59 #include <LocOpe_Gluer.hxx>
60 #include <LocOpe_LinearForm.hxx>
61 #include <Precision.hxx>
62 #include <Standard_ConstructionError.hxx>
63 #include <TColGeom_Array1OfCurve.hxx>
64 #include <TColgp_Array1OfPnt.hxx>
65 #include <TColgp_SequenceOfPnt.hxx>
66 #include <TColStd_Array1OfReal.hxx>
68 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Edge.hxx>
71 #include <TopoDS_Face.hxx>
72 #include <TopoDS_Shape.hxx>
73 #include <TopoDS_Wire.hxx>
74 #include <TopOpeBRepBuild_HBuilder.hxx>
75 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
76 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
77 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
78 #include <TopTools_ListIteratorOfListOfShape.hxx>
79 #include <TopTools_ListOfShape.hxx>
80 #include <TopTools_MapIteratorOfMapOfShape.hxx>
81 #include <TopTools_MapOfShape.hxx>
83 //modified by NIZNHY-PKV Fri Mar 22 16:51:33 2002 f
84 //#include <BRepAlgo_Section.hxx>
85 //#include <BRepAlgo_Common.hxx>
86 //modified by NIZNHY-PKV Fri Mar 22 16:51:35 2002 t
87 //#include <DbgTools.hxx>
89 extern Standard_Boolean BRepFeat_GettraceFEAT();
90 extern Standard_Boolean BRepFeat_GettraceFEATRIB();
93 static void MajMap(const TopoDS_Shape&, // base
94 const LocOpe_LinearForm&,
95 TopTools_DataMapOfShapeListOfShape&, // myMap
96 TopoDS_Shape&, // myFShape
97 TopoDS_Shape&); // myLShape
99 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
101 TopTools_DataMapOfShapeShape&);
103 //=======================================================================
106 //=======================================================================
108 void BRepFeat_MakeLinearForm::Init(const TopoDS_Shape& Sbase,
109 const TopoDS_Wire& W,
110 const Handle(Geom_Plane)& Plane,
112 const gp_Vec& Direc1,
113 const Standard_Integer Mode,
114 const Standard_Boolean Modify)
117 Standard_Boolean trc = BRepFeat_GettraceFEAT();
118 if (trc) cout << "BRepFeat_MakeLinearForm::Init" << endl;
120 Standard_Boolean RevolRib = Standard_False;
124 // modify = 0 if there is no intention to make sliding
125 // = 1 if one tries to make sliding
126 Standard_Boolean Sliding = Modify;
139 myListOfEdges.Clear();
142 TopoDS_Shape aLocalShapeW = W.Oriented(TopAbs_FORWARD);
143 myWire = TopoDS::Wire(aLocalShapeW);
144 // myWire = TopoDS::Wire(W.Oriented(TopAbs_FORWARD));
150 myFuse = Standard_False;
151 else // if(Mode == 1)
152 myFuse = Standard_True;
155 if (myFuse) cout << " Fuse" << endl;
156 if (!myFuse) cout << " Cut" << endl;
161 // ---Determine Tolerance : max tolerance on parameters
162 myTol = Precision::Confusion();
165 exx.Init(myWire, TopAbs_VERTEX);
166 for(; exx.More(); exx.Next()) {
167 const Standard_Real& tol = BRep_Tool::
168 Tolerance(TopoDS::Vertex(exx.Current()));
169 if(tol > myTol) myTol = tol;
172 exx.Init(Sbase, TopAbs_VERTEX);
173 for(; exx.More(); exx.Next()) {
174 const Standard_Real& tol = BRep_Tool::
175 Tolerance(TopoDS::Vertex(exx.Current()));
176 if(tol > myTol) myTol = tol;
179 // ---Control of directions
180 // the wire should be in the rib
181 gp_Vec nulldir(0, 0, 0);
182 if(!myDir1.IsEqual(nulldir, myTol, myTol)) {
183 Standard_Real ang = myDir1.Angle(myDir);
186 if (trc) cout << " Directions must be opposite" << endl;
188 myStatusError = BRepFeat_BadDirect;
195 // Rib is centre in the middle of translation
197 if (trc) cout << " Rib is centre" << endl;
199 const gp_Vec& DirTranslation = (Direc + Direc1) * 0.5;
201 T.SetTranslation(DirTranslation);
202 BRepBuilderAPI_Transform trf(T);
204 myWire = TopoDS::Wire(trf.Shape());
205 myDir = Direc - DirTranslation;
206 myDir1 = Direc1 - DirTranslation;
210 // ---Calculate bounding box
213 TopTools_ListOfShape theList;
217 gp_Pnt FirstCorner, LastCorner;
218 Standard_Real bnd = HeightMax(mySbase, U, FirstCorner, LastCorner);
221 BRepPrimAPI_MakeBox Bndbox(FirstCorner, LastCorner);
222 TopoDS_Solid BndBox = Bndbox.Solid();
225 // ---Construction of the face workplane (section bounding box)
226 BRepLib_MakeFace PlaneF(myPln->Pln(), -6.*myBnd,
227 6.*myBnd, -6.*myBnd, 6.*myBnd);
228 TopoDS_Face PlaneFace = TopoDS::Face(PlaneF.Shape());
230 //modified by NIZNHY-PKV Fri Mar 22 16:49:28 2002 f
231 //BRepAlgo_Common PlaneS(BndBox, PlaneFace);
232 BRepAlgoAPI_Common PlaneS(BndBox, PlaneFace);
233 //modified by NIZNHY-PKV Fri Mar 22 16:49:39 2002 t
235 TopoDS_Shape PlaneSect = PlaneS.Shape();
236 EXP.Init(PlaneSect, TopAbs_WIRE);
237 TopoDS_Wire www = TopoDS::Wire(EXP.Current());
238 BRepLib_MakeFace Bndface(myPln->Pln(), www, Standard_True);
239 TopoDS_Face BndFace = TopoDS::Face(Bndface.Shape());
242 // ---Find support faces of the rib
243 TopoDS_Edge FirstEdge, LastEdge;
244 TopoDS_Face FirstFace, LastFace;
245 TopoDS_Vertex FirstVertex, LastVertex;
247 Standard_Boolean OnFirstFace = Standard_False;
248 Standard_Boolean OnLastFace = Standard_False;
249 Standard_Boolean PtOnFirstEdge = Standard_False;
250 Standard_Boolean PtOnLastEdge = Standard_False;
251 TopoDS_Edge OnFirstEdge, OnLastEdge;
252 OnFirstEdge.Nullify();
253 OnLastEdge.Nullify();
255 Standard_Boolean Data = ExtremeFaces(RevolRib, myBnd, myPln, FirstEdge, LastEdge,
256 FirstFace, LastFace, FirstVertex,
257 LastVertex, OnFirstFace, OnLastFace,
258 PtOnFirstEdge, PtOnLastEdge,
259 OnFirstEdge, OnLastEdge);
263 if (trc) cout << " No Extreme faces" << endl;
265 myStatusError = BRepFeat_NoExtFace;
271 // ---Proofing Point for the side of the wire to be filled - side material
272 gp_Pnt CheckPnt = CheckPoint(FirstEdge, bnd/10., myPln);
274 // Standard_Real f, l;
276 // ---Control sliding valuable
277 // Many cases when the sliding is abandoned
278 Standard_Integer Concavite = 3; // a priori the profile is not concave
280 myFirstPnt = BRep_Tool::Pnt(FirstVertex);
281 myLastPnt = BRep_Tool::Pnt(LastVertex);
283 // SliList : list of faces concerned by the rib
284 TopTools_ListOfShape SliList;
285 SliList.Append(FirstFace);
287 if(Sliding) { // sliding
289 if (trc) cout << " Sliding" << endl;
291 Sliding = Standard_False;
292 Handle(Geom_Surface) s = BRep_Tool::Surface(FirstFace);
293 if (s->DynamicType() ==
294 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
295 s = Handle(Geom_RectangularTrimmedSurface)::
296 DownCast(s)->BasisSurface();
298 if(s->DynamicType() == STANDARD_TYPE(Geom_Plane) ||
299 s->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
300 // if plane or cylinder : sliding is possible
301 Sliding = Standard_True;
305 // Control only start and end points
306 // -> no control at the middle - improve
307 // Controle between Surface and segment between 2 limit points
308 // is too expensive - improve
310 gp_Pnt p1(myFirstPnt.X()+myDir.X(),myFirstPnt.Y()+myDir.Y(),
311 myFirstPnt.Z()+myDir.Z());
312 BRepLib_MakeEdge ee1(myFirstPnt, p1);
313 BRepExtrema_ExtCF ext1(ee1, FirstFace);
314 if(ext1.NbExt() == 1 && ext1.SquareDistance(1)<=BRep_Tool::Tolerance(FirstFace) * BRep_Tool::Tolerance(FirstFace)) {
315 gp_Pnt p2(myLastPnt.X()+myDir.X(),myLastPnt.Y()+myDir.Y(),
316 myLastPnt.Z()+myDir.Z());
317 BRepLib_MakeEdge ee2(myLastPnt, p2);
318 BRepExtrema_ExtCF ext2(ee2, LastFace); // ExtCF : curves and surfaces
319 if(ext2.NbExt() == 1 && ext2.SquareDistance(1)<=BRep_Tool::Tolerance(LastFace) * BRep_Tool::Tolerance(LastFace)) {
320 Sliding = Standard_True;
323 Sliding = Standard_False;
327 Sliding = Standard_False;
331 if(!myDir1.IsEqual(nulldir, Precision::Confusion(), Precision::Confusion())) {
333 gp_Pnt p1(myFirstPnt.X()+myDir1.X(),myFirstPnt.Y()+myDir1.Y(),
334 myFirstPnt.Z()+myDir1.Z());
335 BRepLib_MakeEdge ee1(myFirstPnt, p1);
336 BRepExtrema_ExtCF ext1(ee1, FirstFace);
337 if(ext1.NbExt() == 1 && ext1.SquareDistance(1)<=BRep_Tool::Tolerance(FirstFace) * BRep_Tool::Tolerance(FirstFace)) {
338 gp_Pnt p2(myLastPnt.X()+myDir1.X(),myLastPnt.Y()+myDir1.Y(),
339 myLastPnt.Z()+myDir1.Z());
340 BRepLib_MakeEdge ee2(myLastPnt, p2);
341 BRepExtrema_ExtCF ext2(ee2, LastFace);
342 if(ext2.NbExt() == 1 && ext2.SquareDistance(1)<=BRep_Tool::Tolerance(LastFace) * BRep_Tool::Tolerance(LastFace)) {
343 Sliding = Standard_True;
346 Sliding = Standard_False;
350 Sliding = Standard_False;
356 // Construct a great profile that goes till the bounding box
357 // -> by tangency with the first and the last edge of the Wire
358 // -> by normals to the support faces : statistically better
359 // Intersect everything to find the final profile
362 // ---case of sliding : construction of the profile face
365 if (trc) cout << " still Sliding" << endl;
368 Standard_Boolean ProfileOK;
369 ProfileOK = SlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,BndFace,CheckPnt,
370 FirstFace,LastFace,FirstVertex,LastVertex,
377 cout << "Not computable" << endl;
378 cout << "Face profile not computable" << endl;
381 myStatusError = BRepFeat_NoFaceProf;
387 // ---Propagation on faces of the initial shape
388 // to find the faces concerned by the rib
389 Standard_Boolean falseside = Standard_True;
390 Sliding = Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
391 // Control if there is everything required to have the material at the proper side
392 if(falseside == Standard_False) {
394 cout << "Verify plane and wire orientation" << endl;
396 myStatusError = BRepFeat_FalseSide;
403 // ---Generation of the base of the rib profile
407 TopoDS_Edge thePreviousEdge;
409 thePreviousEdge.Nullify();
411 // calculate the number of edges to fill the map
412 Standard_Integer counter = 1;
414 // ---case of sliding
415 if(Sliding && !myListOfEdges.IsEmpty()) {
416 BRepTools_WireExplorer EX1(myWire);
417 for(; EX1.More(); EX1.Next()) {
418 const TopoDS_Edge& E = EX1.Current();
419 if(!myLFMap.IsBound(E)) {
420 TopTools_ListOfShape theTmpList;
421 myLFMap.Bind(E, theTmpList );
423 if(E.IsSame(FirstEdge)) {
425 Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
426 cc = new Geom_TrimmedCurve(cc, f, l);
428 if(!FirstEdge.IsSame(LastEdge)) {
429 pt = BRep_Tool::Pnt(TopExp::LastVertex(E,Standard_True));
433 Standard_Real fpar = IntPar(cc, myFirstPnt);
434 Standard_Real lpar = IntPar(cc, pt);
440 if(thePreviousEdge.IsNull()) {
441 BRepLib_MakeVertex v1(myFirstPnt);
442 BRepLib_MakeVertex v2(pt);
443 BRepLib_MakeEdge e(cc, v1, v2);
444 ee1 = TopoDS::Edge(e.Shape());
447 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
448 BRepLib_MakeVertex v2(pt);
450 BRepLib_MakeEdge e(cc, v1, v2);
451 ee1 = TopoDS::Edge(e.Shape());
453 TopoDS_Shape aLocalShape = ee1.Oriented(E.Orientation());
454 ee1 = TopoDS::Edge(aLocalShape);
455 // ee1 = TopoDS::Edge(ee1.Oriented(E.Orientation()));
456 if(counter == 1) theFV = TopExp::FirstVertex(ee1,Standard_True);
457 myLFMap(E).Append(ee1);
459 thePreviousEdge = ee1;
466 // Case of several edges
467 if(!FirstEdge.IsSame(LastEdge)) {
468 for(; EX1.More(); EX1.Next()) {
469 const TopoDS_Edge& E = EX1.Current();
470 if(!myLFMap.IsBound(E)) {
471 TopTools_ListOfShape thelist1;
472 myLFMap.Bind(E, thelist1);
476 if(!E.IsSame(LastEdge)) {
477 Handle(Geom_Curve) ccc = BRep_Tool::Curve(E, f, l);
478 TopoDS_Vertex v1, v2;
479 if(!thePreviousEdge.IsNull()) {
480 v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
481 v2 = TopExp::LastVertex(E,Standard_True);
484 // v1 = TopExp::LastVertex(E,Standard_True);
485 v1 = TopExp::FirstVertex(E,Standard_True);
486 v2 = TopExp::LastVertex(E,Standard_True);
488 BRepLib_MakeEdge E1(ccc, v1, v2);
489 TopoDS_Edge E11 = TopoDS::Edge(E1.Shape());
490 TopoDS_Shape aLocalShape = E11.Oriented(E.Orientation());
491 E11 = TopoDS::Edge(aLocalShape);
492 // E11 = TopoDS::Edge(E11.Oriented(E.Orientation()));
493 thePreviousEdge = E11;
494 myLFMap(E).Append(E11);
496 if(counter == 1) theFV = TopExp::FirstVertex(E11,Standard_True);
500 Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
501 gp_Pnt pf = BRep_Tool::Pnt(TopExp::FirstVertex(E,Standard_True));
502 gp_Pnt pl = myLastPnt;
504 if(thePreviousEdge.IsNull()) {
505 BRepLib_MakeEdge e(cc, pf , pl);
506 ee = TopoDS::Edge(e.Shape());
509 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
510 BRepLib_MakeVertex v2(pl);
511 BRepLib_MakeEdge e(cc, v1, v2);
512 ee = TopoDS::Edge(e.Shape());
514 TopoDS_Shape aLocalShape = ee.Oriented(E.Orientation());
515 ee = TopoDS::Edge(aLocalShape);
516 // ee = TopoDS::Edge(ee.Oriented(E.Orientation()));
518 myLFMap(E).Append(ee);
519 if(counter == 1) theFV = TopExp::FirstVertex(ee,Standard_True);
520 thePreviousEdge = ee;
527 TopTools_ListIteratorOfListOfShape it(myListOfEdges);
528 Standard_Boolean FirstOK = Standard_False;
529 Standard_Boolean LastOK = Standard_False;
531 gp_Pnt theLastPnt = myLastPnt;
532 Standard_Integer sens = 0;
533 TopoDS_Edge theEdge, theLEdge, theFEdge;
534 Standard_Integer counter1 = counter;
535 TopTools_ListOfShape NewListOfEdges;
536 NewListOfEdges.Clear();
538 const TopoDS_Edge& edg = TopoDS::Edge(it.Value());
541 Handle(Geom_Curve) ccc = BRep_Tool::Curve(edg, f, l);
542 Handle(Geom_TrimmedCurve) cc = new Geom_TrimmedCurve(ccc, f, l);
543 if ( edg.Orientation() == TopAbs_REVERSED) cc->Reverse();
545 fp = cc->Value(cc->FirstParameter());
546 lp = cc->Value(cc->LastParameter());
547 Standard_Real dist = fp.Distance(theLastPnt);
550 LastOK = Standard_True;
553 dist = lp.Distance(theLastPnt);
556 LastOK = Standard_True;
560 Standard_Integer FirstFlag = 0;
561 if(sens==1 && lp.Distance(myFirstPnt) <= myTol) {
562 FirstOK = Standard_True;
565 else if(sens==2 && fp.Distance(myFirstPnt) <= myTol) {
566 FirstOK = Standard_True;
572 Standard_Real fpar = cc->FirstParameter();
573 Standard_Real lpar = cc->LastParameter();
575 if(thePreviousEdge.IsNull()) {
576 BRepLib_MakeEdge e(cc, fpar, lpar);
577 eeee = TopoDS::Edge(e.Shape());
580 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
581 BB.UpdateVertex(v1, dist);
582 BRepLib_MakeVertex v2(cc->Value(lpar));
583 TopoDS_Vertex nv=v2.Vertex();
584 BRepLib_MakeEdge e(cc, v1, nv);
585 eeee = TopoDS::Edge(e.Shape());
589 if(thePreviousEdge.IsNull()) {
590 BRepLib_MakeVertex v1(cc->Value(fpar));
591 BRepLib_MakeEdge e(cc, v1, theFV);
592 eeee = TopoDS::Edge(e.Shape());
595 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
596 BRepLib_MakeEdge e(cc, v1, theFV);
597 eeee = TopoDS::Edge(e.Shape());
601 thePreviousEdge = eeee;
603 if(counter == 1) theFV = TopExp::FirstVertex(eeee,Standard_True);
605 NewListOfEdges.Append(edg);
610 theLastPnt = BRep_Tool::Pnt(TopExp::LastVertex(theEdge,Standard_True));
616 else if(FirstFlag == 2) {
621 myListOfEdges.Remove(it);
622 it.Initialize(myListOfEdges);
623 LastOK = Standard_False;
625 else if(it.More()) it.Next();
627 Sliding = Standard_False;
634 TopTools_DataMapOfShapeListOfShape SlidMap;
637 if(Sliding && counter1 > counter) {
638 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm;
639 TopExp_Explorer EX2(w, TopAbs_EDGE);
640 Standard_Integer ii = 0;
641 for(; EX2.More(); EX2.Next()) {
642 const TopoDS_Edge& E = TopoDS::Edge(EX2.Current());
644 if(ii >= counter && ii <= counter1) {
645 it.Initialize(NewListOfEdges);
646 Standard_Integer jj = 0;
647 for(; it.More(); it.Next()) {
648 const TopoDS_Edge& e2 = TopoDS::Edge(it.Value());
650 if(jj== (ii - counter +1)) {
651 itm.Initialize(mySlface);
652 for(; itm.More(); itm.Next()) {
653 const TopoDS_Face& fac = TopoDS::Face(itm.Key());
654 const TopTools_ListOfShape& ledg = itm.Value();
655 TopTools_ListIteratorOfListOfShape itedg(ledg);
656 //Standard_Integer iiii = 0;
657 for(; itedg.More(); itedg.Next()) {
658 const TopoDS_Edge& e1 = TopoDS::Edge(itedg.Value());
660 if(!SlidMap.IsBound(fac)) {
661 TopTools_ListOfShape thelist2;
662 SlidMap.Bind(fac, thelist2);
664 SlidMap(fac).Append(E);
678 // ---Arguments of LocOpe_LinearForm : arguments of the prism sliding
681 BB.MakeFace(F, myPln, myTol);
682 w.Closed (BRep_Tool::IsClosed (w));
684 // BRepLib_MakeFace F(myPln->Pln(),w, Standard_True);
691 // ---Case without sliding : construction of the profile face
695 if (Modify) cout << " Sliding failure" << endl;
696 cout << " no Sliding" << endl;
700 Standard_Boolean ProfileOK;
701 ProfileOK = NoSlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,
702 bnd,BndFace,CheckPnt,
703 FirstFace,LastFace,FirstVertex,LastVertex,
704 FirstEdge,LastEdge,OnFirstFace,OnLastFace);
710 cout << "Not computable" << endl;
711 cout << " Face profile not computable" << endl;
714 myStatusError = BRepFeat_NoFaceProf;
720 // ---Propagation on faces of the initial shape
721 // to find the faces concerned by the rib
722 Standard_Boolean falseside = Standard_True;
723 Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
724 // Control if there is everything required to have the material at the proper side
725 if(falseside == Standard_False) {
727 cout << "Verify plane and wire orientation" << endl;
729 myStatusError = BRepFeat_FalseSide;
736 TopTools_ListIteratorOfListOfShape it;
737 it.Initialize(SliList);
741 BB.MakeShell(TopoDS::Shell(comp));
743 for(; it.More(); it.Next()) {
744 BB.Add(comp, it.Value());
746 comp.Closed (BRep_Tool::IsClosed (comp));
757 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
758 TopTools_ListOfShape thelist3;
759 myMap.Bind(exp.Current(), thelist3);
760 myMap(exp.Current()).Append(exp.Current());
765 //=======================================================================
767 //purpose : add des element de collage
768 //=======================================================================
770 void BRepFeat_MakeLinearForm::Add(const TopoDS_Edge& E,
771 const TopoDS_Face& F)
774 Standard_Boolean trc = BRepFeat_GettraceFEAT();
775 if (trc) cout << "BRepFeat_MakeLinearForm::Add" << endl;
777 if(mySlface.IsEmpty()) {
779 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
780 if (exp.Current().IsSame(F)) {
785 throw Standard_ConstructionError();
788 if (!mySlface.IsBound(F)) {
789 TopTools_ListOfShape thelist;
790 mySlface.Bind(F, thelist);
792 TopTools_ListIteratorOfListOfShape itl(mySlface(F));
793 for (; itl.More();itl.Next()) {
794 if (itl.Value().IsSame(E)) {
799 mySlface(F).Append(E);
806 //=======================================================================
808 //purpose : construction of rib from a profile and the initial shape
809 //=======================================================================
811 void BRepFeat_MakeLinearForm::Perform()
814 Standard_Boolean trc = BRepFeat_GettraceFEAT();
815 if (trc) cout << "BRepFeat_MakeLinearForm::Perform()" << endl;
817 if(mySbase.IsNull() || mySkface.IsNull() || myPbase.IsNull()) {
819 if (trc) cout << " Fields not initialized" << endl;
821 myStatusError = BRepFeat_NotInitialized;
826 gp_Vec nulldir(0, 0, 0);
828 Standard_Real Length = myDir.Magnitude() + myDir1.Magnitude();
832 if(!mySUntil.IsNull())
833 myPerfSelection = BRepFeat_SelectionU;
835 myPerfSelection = BRepFeat_NoSelection;
838 gp_Vec V = Length*dir;
840 LocOpe_LinearForm theForm;
842 if(myDir1.IsEqual(nulldir, Precision::Confusion(), Precision::Confusion()))
843 theForm.Perform(myPbase, V, myFirstPnt, myLastPnt);
845 theForm.Perform(myPbase, V, myDir1, myFirstPnt, myLastPnt);
847 TopoDS_Shape VraiForm = theForm.Shape(); // primitive of the rib
849 myFacesForDraft.Append(theForm.FirstShape());
850 myFacesForDraft.Append(theForm.LastShape());
851 MajMap(myPbase,theForm,myMap,myFShape,myLShape); // management of descendants
853 TopExp_Explorer exx(myPbase, TopAbs_EDGE);
854 for(; exx.More(); exx.Next()) {
855 const TopoDS_Edge& e = TopoDS::Edge(exx.Current());
856 if(!myMap.IsBound(e)) {
858 if (trc) cout << " Sliding face not in Base shape" << endl;
860 myStatusError = BRepFeat_IncSlidFace;
867 SetGluedFaces(mySlface, theForm, myGluedF); // management of sliding faces
869 if(!myGluedF.IsEmpty() && !mySUntil.IsNull()) {
873 cout << "The case is not computable" << endl;
874 cout << " Glued faces not empty and Until shape not null" << endl;
877 myStatusError = BRepFeat_InvShape;
886 TopExp_Explorer expr(mySbase, TopAbs_FACE);
887 char nom1[20], nom2[20];
888 Standard_Integer ii = 0;
889 for(; expr.More(); expr.Next()) {
891 sprintf(nom1, "faceinitial_%d", ii);
892 DBRep::Set(nom1, expr.Current());
893 Standard_Integer jj = 0;
894 const TopTools_ListOfShape& list = Modified(expr.Current());
895 TopTools_ListIteratorOfListOfShape ite(list);
896 for(; ite.More(); ite.Next()) {
898 sprintf(nom2, "facemodifie_%d_%d", ii, jj);
899 DBRep::Set(nom2, ite.Value());
903 expr.Init(myWire, TopAbs_EDGE);
905 for(; expr.More(); expr.Next()) {
907 sprintf(nom1, "edgeinitial_%d", ii);
908 DBRep::Set(nom1, expr.Current());
909 Standard_Integer jj = 0;
910 const TopTools_ListOfShape& genf = Generated(expr.Current());
911 TopTools_ListIteratorOfListOfShape ite(genf);
912 for(; ite.More(); ite.Next()) {
914 sprintf(nom2, "egdegeneree_%d_%d", ii, jj);
915 DBRep::Set(nom2, ite.Value());
921 //=======================================================================
922 //function : Propagate
923 //purpose : propagation on faces of the initial shape, find
924 // faces concerned by the rib
925 //=======================================================================
926 Standard_Boolean BRepFeat_MakeLinearForm::Propagate(TopTools_ListOfShape& SliList,
927 const TopoDS_Face& fac,
928 const gp_Pnt& Firstpnt,
929 const gp_Pnt& Lastpnt,
930 Standard_Boolean& falseside)
933 Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
934 if (trc) cout << "BRepFeat_MakeLinearForm::Propagate" << endl;
936 gp_Pnt Firstpoint = Firstpnt;
937 gp_Pnt Lastpoint = Lastpnt;
939 Standard_Boolean result = Standard_True;
940 TopoDS_Face CurrentFace, saveFace;
941 CurrentFace = TopoDS::Face(SliList.First());
942 saveFace = CurrentFace;
944 Standard_Boolean LastOK = Standard_False, FirstOK= Standard_False;
945 Standard_Boolean v1OK = Standard_False, v2OK= Standard_False;
946 TopoDS_Vertex v1, v2, v3, v4, ve1, ve2;
948 //modified by NIZNHY-PKV Fri Mar 22 16:50:24 2002 f
949 //BRepAlgo_Section sect (fac, CurrentFace, Standard_False);
950 BRepAlgoAPI_Section sect (fac, CurrentFace, Standard_False);
951 //modified by NIZNHY-PKV Fri Mar 22 16:50:32 2002 t
953 sect.Approximation(Standard_True);
959 Standard_Real t1 = 0., t2 = 0.;
960 Standard_Boolean c1f, c2f, c1l, c2l;
962 for (Ex.Init(sect.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
963 ec = TopoDS::Edge(Ex.Current());
964 v1 = TopExp::FirstVertex(ec,Standard_True);
965 v2 = TopExp::LastVertex(ec,Standard_True);
966 p1 = BRep_Tool::Pnt(v1);
967 p2 = BRep_Tool::Pnt(v2);
968 t1 = BRep_Tool::Tolerance(v1);
969 t2 = BRep_Tool::Tolerance(v2);
970 c1f = p1.Distance(Firstpoint)<=t1;
971 c2f = p2.Distance(Firstpoint)<=t2;
972 c1l = p1.Distance(Lastpoint)<=t1;
973 c2l = p2.Distance(Lastpoint)<=t2;
974 if (c1f || c2f || c1l|| c2l) {
976 if (c1f || c1l) v1OK=Standard_True;
977 if (c2f || c2l) v2OK=Standard_True;
978 if (c1f || c2f) FirstOK=Standard_True;
979 if (c1l || c2l) LastOK=Standard_True;
985 falseside = Standard_False;
986 return Standard_False;
988 TopTools_ListOfShape thelist;
989 mySlface.Bind(CurrentFace, thelist);
990 mySlface(CurrentFace).Append(eb);
992 myListOfEdges.Clear();
993 myListOfEdges.Append(eb);
995 // two points are on the same face.
996 if(LastOK && FirstOK) {
1000 TopTools_IndexedDataMapOfShapeListOfShape mapedges;
1001 TopExp::MapShapesAndAncestors(mySbase, TopAbs_EDGE, TopAbs_FACE, mapedges);
1003 TopoDS_Edge FirstEdge;
1006 TopoDS_Vertex Vprevious;
1010 while (!(LastOK && FirstOK)) {
1020 // find edge connected to v1 or v2:
1021 for (ex.Init(CurrentFace, TopAbs_EDGE); ex.More(); ex.Next()) {
1022 const TopoDS_Edge& rfe = TopoDS::Edge(ex.Current());
1024 BRepExtrema_ExtPC projF(Vprevious, rfe);
1026 if(projF.IsDone() && projF.NbExt() >=1) {
1027 Standard_Real dist2min = RealLast();
1028 Standard_Integer index = 0;
1029 for (Standard_Integer sol =1 ; sol <= projF.NbExt(); sol++) {
1030 if (projF.SquareDistance(sol) <= dist2min) {
1032 dist2min = projF.SquareDistance(sol);
1036 if (dist2min <= BRep_Tool::Tolerance(rfe) * BRep_Tool::Tolerance(rfe)) {
1038 // If the edge is not perpendicular to the plane of the rib
1039 // it is required to set Sliding(result) to false.
1041 result=Standard_False;
1042 ve1 = TopExp::FirstVertex(rfe,Standard_True);
1043 ve2 = TopExp::LastVertex(rfe,Standard_True);
1044 BRepExtrema_ExtPF perp(ve1, fac);
1045 if (perp.IsDone()) {
1046 gp_Pnt pe1=perp.Point(1);
1047 perp.Perform(ve2, fac);
1048 if (perp.IsDone()) {
1049 gp_Pnt pe2=perp.Point(1);
1050 if (pe1.Distance(pe2)<=BRep_Tool::Tolerance(rfe))
1051 result=Standard_True;
1061 const TopTools_ListOfShape& L = mapedges.FindFromKey(FirstEdge);
1062 TopTools_ListIteratorOfListOfShape It(L);
1064 for (; It.More(); It.Next()) {
1065 const TopoDS_Face& FF = TopoDS::Face(It.Value());
1066 if (!FF.IsSame(CurrentFace)) {
1072 //modified by NIZNHY-PKV Fri Mar 22 16:50:53 2002 f
1073 //BRepAlgo_Section sectf (fac, CurrentFace, Standard_False);
1074 BRepAlgoAPI_Section sectf (fac, CurrentFace, Standard_False);
1075 //modified by NIZNHY-PKV Fri Mar 22 16:51:03 2002 t
1076 sectf.Approximation(Standard_True);
1080 for (Ex.Init(sectf.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
1081 edg1 = TopoDS::Edge(Ex.Current());
1082 v1=TopExp::FirstVertex(edg1,Standard_True);
1083 v2=TopExp::LastVertex(edg1,Standard_True);
1084 t1 = BRep_Tool::Tolerance(v1);
1085 t2 = BRep_Tool::Tolerance(v2);
1086 p1 = BRep_Tool::Pnt(v1);
1087 p2 = BRep_Tool::Pnt(v2);
1088 v1OK = p1.Distance(ptprev)<=t1;
1089 v2OK = p2.Distance(ptprev)<=t2;
1090 if (v1OK || v2OK) break;
1095 dp = p2.Distance(Firstpoint);
1097 FirstOK = Standard_True;
1098 BB.UpdateVertex(v2, dp);
1102 dp = p2.Distance(Lastpoint);
1104 LastOK = Standard_True;
1105 BB.UpdateVertex(v2, dp);
1111 dp = p1.Distance(Firstpoint);
1113 FirstOK = Standard_True;
1114 BB.UpdateVertex(v1, dp);
1118 dp = p1.Distance(Lastpoint);
1120 LastOK = Standard_True;
1121 BB.UpdateVertex(v1, dp);
1126 // end by chaining the section
1127 return Standard_False;
1129 TopTools_ListOfShape thelist1;
1130 mySlface.Bind(CurrentFace, thelist1);
1131 mySlface(CurrentFace).Append(edg1);
1132 myListOfEdges.Append(edg1);
1139 //=======================================================================
1141 //purpose : management of descendants
1142 //=======================================================================
1144 static void MajMap(const TopoDS_Shape& theB,
1145 const LocOpe_LinearForm& theP,
1146 TopTools_DataMapOfShapeListOfShape& theMap, // myMap
1147 TopoDS_Shape& theFShape, // myFShape
1148 TopoDS_Shape& theLShape) // myLShape
1150 TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
1152 theFShape = exp.Current();
1153 TopTools_ListOfShape thelist;
1154 theMap.Bind(theFShape, thelist);
1155 for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
1156 theMap(theFShape).Append(exp.Current());
1160 exp.Init(theP.LastShape(),TopAbs_WIRE);
1162 theLShape = exp.Current();
1163 TopTools_ListOfShape thelist1;
1164 theMap.Bind(theLShape, thelist1);
1165 for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
1166 theMap(theLShape).Append(exp.Current());
1170 for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
1171 if (!theMap.IsBound(exp.Current())) {
1172 TopTools_ListOfShape thelist2;
1173 theMap.Bind(exp.Current(), thelist2);
1174 theMap(exp.Current()) = theP.Shapes(exp.Current());
1179 //=======================================================================
1180 //function : SetGluedFaces
1181 //purpose : management of faces of gluing
1182 //=======================================================================
1184 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
1185 LocOpe_LinearForm& thePrism,
1186 TopTools_DataMapOfShapeShape& theMap)
1189 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(theSlmap);
1190 if(!theSlmap.IsEmpty()) {
1191 for (; itm.More(); itm.Next()) {
1192 const TopoDS_Face& fac = TopoDS::Face(itm.Key());
1193 const TopTools_ListOfShape& ledg = itm.Value();
1194 TopTools_ListIteratorOfListOfShape it;
1195 for (it.Initialize(ledg); it.More(); it.Next()) {
1196 const TopTools_ListOfShape& gfac = thePrism.Shapes(it.Value());
1197 if (gfac.Extent() != 1) {
1199 cout << "Pb SetGluedFace" << endl;
1202 theMap.Bind(gfac.First(),fac);