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.
17 #include <BRepFeat_MakeLinearForm.ixx>
19 #include <BRepFeat.hxx>
22 #include <LocOpe_LinearForm.hxx>
23 #include <LocOpe_Gluer.hxx>
24 #include <LocOpe_FindEdges.hxx>
32 #include <gp_Vec2d.hxx>
33 #include <gp_Pnt2d.hxx>
35 #include <Geom_Curve.hxx>
37 #include <Geom2d_Curve.hxx>
38 #include <Geom2d_Line.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Geom_Surface.hxx>
42 #include <Geom_CylindricalSurface.hxx>
43 #include <Geom_RectangularTrimmedSurface.hxx>
45 #include <Geom_TrimmedCurve.hxx>
46 #include <GeomProjLib.hxx>
48 #include <Geom2d_Curve.hxx>
49 #include <Geom2d_Curve.hxx>
51 #include <TColgp_SequenceOfPnt.hxx>
53 #include <TColStd_Array1OfReal.hxx>
54 #include <IntRes2d_IntersectionPoint.hxx>
56 #include <BRepTools_WireExplorer.hxx>
58 #include <BRep_Tool.hxx>
59 #include <BRep_Builder.hxx>
61 #include <TopExp_Explorer.hxx>
64 #include <TopTools_MapOfShape.hxx>
65 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
66 #include <TopTools_ListOfShape.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
69 #include <TopTools_MapIteratorOfMapOfShape.hxx>
70 #include <TopOpeBRepBuild_HBuilder.hxx>
71 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
73 #include <TColgp_Array1OfPnt.hxx>
75 #include <TColGeom_Array1OfCurve.hxx>
78 #include <TopoDS_Shape.hxx>
79 #include <TopoDS_Face.hxx>
81 #include <BRepLib_MakeVertex.hxx>
82 #include <BRepLib_MakeEdge.hxx>
83 #include <BRepLib_MakeFace.hxx>
85 #include <BRepTools.hxx>
87 #include <BRepBuilderAPI.hxx>
88 #include <BRepPrimAPI_MakeBox.hxx>
89 #include <BRepBuilderAPI_MakeFace.hxx>
91 //modified by NIZNHY-PKV Fri Mar 22 16:51:33 2002 f
92 //#include <BRepAlgo_Section.hxx>
93 //#include <BRepAlgo_Common.hxx>
94 #include <BRepAlgoAPI_Section.hxx>
95 #include <BRepAlgoAPI_Common.hxx>
96 //modified by NIZNHY-PKV Fri Mar 22 16:51:35 2002 t
98 #include <BRepExtrema_ExtPC.hxx>
99 #include <BRepExtrema_ExtPF.hxx>
100 #include <BRepExtrema_ExtCF.hxx>
102 #include <BRepTools_Modifier.hxx>
103 #include <BRepTools_TrsfModification.hxx>
105 #include <Standard_ConstructionError.hxx>
107 #include <Precision.hxx>
109 #include <GeomLProp_CLProps.hxx>
111 #include <BRepBuilderAPI_Transform.hxx>
112 #include <BRepLib_MakeWire.hxx>
113 //#include <DbgTools.hxx>
116 extern Standard_Boolean BRepFeat_GettraceFEAT();
117 extern Standard_Boolean BRepFeat_GettraceFEATRIB();
120 static void MajMap(const TopoDS_Shape&, // base
121 const LocOpe_LinearForm&,
122 TopTools_DataMapOfShapeListOfShape&, // myMap
123 TopoDS_Shape&, // myFShape
124 TopoDS_Shape&); // myLShape
126 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
128 TopTools_DataMapOfShapeShape&);
130 //=======================================================================
133 //=======================================================================
135 void BRepFeat_MakeLinearForm::Init(const TopoDS_Shape& Sbase,
136 const TopoDS_Wire& W,
137 const Handle(Geom_Plane)& Plane,
139 const gp_Vec& Direc1,
140 const Standard_Integer Mode,
141 const Standard_Boolean Modify)
144 Standard_Boolean trc = BRepFeat_GettraceFEAT();
145 if (trc) cout << "BRepFeat_MakeLinearForm::Init" << endl;
147 Standard_Boolean RevolRib = Standard_False;
151 // modify = 0 if there is no intention to make sliding
152 // = 1 if one tries to make sliding
153 Standard_Boolean Sliding = Modify;
166 myListOfEdges.Clear();
169 TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
170 myWire = TopoDS::Wire(aLocalShape);
171 // myWire = TopoDS::Wire(W.Oriented(TopAbs_FORWARD));
177 myFuse = Standard_False;
178 else // if(Mode == 1)
179 myFuse = Standard_True;
182 if (myFuse) cout << " Fuse" << endl;
183 if (!myFuse) cout << " Cut" << endl;
188 // ---Determine Tolerance : max tolerance on parameters
189 myTol = Precision::Confusion();
192 exx.Init(myWire, TopAbs_VERTEX);
193 for(; exx.More(); exx.Next()) {
194 const Standard_Real& tol = BRep_Tool::
195 Tolerance(TopoDS::Vertex(exx.Current()));
196 if(tol > myTol) myTol = tol;
199 exx.Init(Sbase, TopAbs_VERTEX);
200 for(; exx.More(); exx.Next()) {
201 const Standard_Real& tol = BRep_Tool::
202 Tolerance(TopoDS::Vertex(exx.Current()));
203 if(tol > myTol) myTol = tol;
206 // ---Control of directions
207 // the wire should be in the rib
208 gp_Vec nulldir(0, 0, 0);
209 if(!myDir1.IsEqual(nulldir, myTol, myTol)) {
210 Standard_Real ang = myDir1.Angle(myDir);
213 if (trc) cout << " Directions must be opposite" << endl;
215 myStatusError = BRepFeat_BadDirect;
222 // Rib is centre in the middle of translation
224 if (trc) cout << " Rib is centre" << endl;
226 const gp_Vec& DirTranslation = (Direc + Direc1) * 0.5;
228 T.SetTranslation(DirTranslation);
229 BRepBuilderAPI_Transform trf(T);
231 myWire = TopoDS::Wire(trf.Shape());
232 myDir = Direc - DirTranslation;
233 myDir1 = Direc1 - DirTranslation;
237 // ---Calculate bounding box
240 TopTools_ListOfShape theList;
244 gp_Pnt FirstCorner, LastCorner;
245 Standard_Real bnd = HeightMax(mySbase, U, FirstCorner, LastCorner);
248 BRepPrimAPI_MakeBox Bndbox(FirstCorner, LastCorner);
249 TopoDS_Solid BndBox = Bndbox.Solid();
252 // ---Construction of the face workplane (section bounding box)
253 BRepLib_MakeFace PlaneF(myPln->Pln(), -6.*myBnd,
254 6.*myBnd, -6.*myBnd, 6.*myBnd);
255 TopoDS_Face PlaneFace = TopoDS::Face(PlaneF.Shape());
257 //modified by NIZNHY-PKV Fri Mar 22 16:49:28 2002 f
258 //BRepAlgo_Common PlaneS(BndBox, PlaneFace);
259 BRepAlgoAPI_Common PlaneS(BndBox, PlaneFace);
260 //modified by NIZNHY-PKV Fri Mar 22 16:49:39 2002 t
262 TopoDS_Shape PlaneSect = PlaneS.Shape();
263 EXP.Init(PlaneSect, TopAbs_WIRE);
264 TopoDS_Wire www = TopoDS::Wire(EXP.Current());
265 BRepLib_MakeFace Bndface(myPln->Pln(), www, Standard_True);
266 TopoDS_Face BndFace = TopoDS::Face(Bndface.Shape());
269 // ---Find support faces of the rib
270 TopoDS_Edge FirstEdge, LastEdge;
271 TopoDS_Face FirstFace, LastFace;
272 TopoDS_Vertex FirstVertex, LastVertex;
274 Standard_Boolean OnFirstFace = Standard_False;
275 Standard_Boolean OnLastFace = Standard_False;
276 Standard_Boolean PtOnFirstEdge = Standard_False;
277 Standard_Boolean PtOnLastEdge = Standard_False;
278 TopoDS_Edge OnFirstEdge, OnLastEdge;
279 OnFirstEdge.Nullify();
280 OnLastEdge.Nullify();
282 Standard_Boolean Data = ExtremeFaces(RevolRib, myBnd, myPln, FirstEdge, LastEdge,
283 FirstFace, LastFace, FirstVertex,
284 LastVertex, OnFirstFace, OnLastFace,
285 PtOnFirstEdge, PtOnLastEdge,
286 OnFirstEdge, OnLastEdge);
290 if (trc) cout << " No Extreme faces" << endl;
292 myStatusError = BRepFeat_NoExtFace;
298 // ---Proofing Point for the side of the wire to be filled - side material
299 gp_Pnt CheckPnt = CheckPoint(FirstEdge, bnd/10., myPln);
301 // Standard_Real f, l;
303 // ---Control sliding valuable
304 // Many cases when the sliding is abandoned
305 Standard_Integer Concavite = 3; // a priori the profile is not concave
307 myFirstPnt = BRep_Tool::Pnt(FirstVertex);
308 myLastPnt = BRep_Tool::Pnt(LastVertex);
310 // SliList : list of faces concerned by the rib
311 TopTools_ListOfShape SliList;
312 SliList.Append(FirstFace);
314 if(Sliding) { // sliding
316 if (trc) cout << " Sliding" << endl;
318 Standard_Boolean Sliding = Standard_False;
319 Handle(Geom_Surface) s = BRep_Tool::Surface(FirstFace);
320 if (s->DynamicType() ==
321 STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
322 s = Handle(Geom_RectangularTrimmedSurface)::
323 DownCast(s)->BasisSurface();
325 if(s->DynamicType() == STANDARD_TYPE(Geom_Plane) ||
326 s->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
327 // if plane or cylinder : sliding is possible
328 Sliding = Standard_True;
332 // Control only start and end points
333 // -> no control at the middle - improve
334 // Controle between Surface and segment between 2 limit points
335 // is too expensive - improve
337 gp_Pnt p1(myFirstPnt.X()+myDir.X(),myFirstPnt.Y()+myDir.Y(),
338 myFirstPnt.Z()+myDir.Z());
339 BRepLib_MakeEdge ee1(myFirstPnt, p1);
340 BRepExtrema_ExtCF ext1(ee1, FirstFace);
341 if(ext1.NbExt() == 1 && ext1.SquareDistance(1)<=BRep_Tool::Tolerance(FirstFace) * BRep_Tool::Tolerance(FirstFace)) {
342 gp_Pnt p2(myLastPnt.X()+myDir.X(),myLastPnt.Y()+myDir.Y(),
343 myLastPnt.Z()+myDir.Z());
344 BRepLib_MakeEdge ee2(myLastPnt, p2);
345 BRepExtrema_ExtCF ext2(ee2, LastFace); // ExtCF : curves and surfaces
346 if(ext2.NbExt() == 1 && ext2.SquareDistance(1)<=BRep_Tool::Tolerance(LastFace) * BRep_Tool::Tolerance(LastFace)) {
347 Sliding = Standard_True;
350 Sliding = Standard_False;
354 Sliding = Standard_False;
358 if(!myDir1.IsEqual(nulldir, Precision::Confusion(), Precision::Confusion())) {
360 gp_Pnt p1(myFirstPnt.X()+myDir1.X(),myFirstPnt.Y()+myDir1.Y(),
361 myFirstPnt.Z()+myDir1.Z());
362 BRepLib_MakeEdge ee1(myFirstPnt, p1);
363 BRepExtrema_ExtCF ext1(ee1, FirstFace);
364 if(ext1.NbExt() == 1 && ext1.SquareDistance(1)<=BRep_Tool::Tolerance(FirstFace) * BRep_Tool::Tolerance(FirstFace)) {
365 gp_Pnt p2(myLastPnt.X()+myDir1.X(),myLastPnt.Y()+myDir1.Y(),
366 myLastPnt.Z()+myDir1.Z());
367 BRepLib_MakeEdge ee2(myLastPnt, p2);
368 BRepExtrema_ExtCF ext2(ee2, LastFace);
369 if(ext2.NbExt() == 1 && ext2.SquareDistance(1)<=BRep_Tool::Tolerance(LastFace) * BRep_Tool::Tolerance(LastFace)) {
370 Sliding = Standard_True;
373 Sliding = Standard_False;
377 Sliding = Standard_False;
383 // Construct a great profile that goes till the bounding box
384 // -> by tangency with the first and the last edge of the Wire
385 // -> by normals to the support faces : statistically better
386 // Intersect everything to find the final profile
389 // ---case of sliding : construction of the profile face
392 if (trc) cout << " still Sliding" << endl;
395 Standard_Boolean ProfileOK;
396 ProfileOK = SlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,BndFace,CheckPnt,
397 FirstFace,LastFace,FirstVertex,LastVertex,
404 cout << "Not computable" << endl;
405 cout << "Face profile not computable" << endl;
408 myStatusError = BRepFeat_NoFaceProf;
414 // ---Propagation on faces of the initial shape
415 // to find the faces concerned by the rib
416 Standard_Boolean falseside = Standard_True;
417 Sliding = Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
418 // Control if there is everything required to have the material at the proper side
419 if(falseside == Standard_False) {
421 cout << "Verify plane and wire orientation" << endl;
423 myStatusError = BRepFeat_FalseSide;
430 // ---Generation of the base of the rib profile
434 TopoDS_Edge thePreviousEdge;
436 thePreviousEdge.Nullify();
438 // calculate the number of edges to fill the map
439 Standard_Integer counter = 1;
441 // ---case of sliding
442 if(Sliding && !myListOfEdges.IsEmpty()) {
443 BRepTools_WireExplorer EX1(myWire);
444 for(; EX1.More(); EX1.Next()) {
445 const TopoDS_Edge& E = EX1.Current();
446 if(!myLFMap.IsBound(E)) {
447 TopTools_ListOfShape theTmpList;
448 myLFMap.Bind(E, theTmpList );
450 if(E.IsSame(FirstEdge)) {
452 Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
453 cc = new Geom_TrimmedCurve(cc, f, l);
455 if(!FirstEdge.IsSame(LastEdge)) {
456 pt = BRep_Tool::Pnt(TopExp::LastVertex(E,Standard_True));
460 Standard_Real fpar = IntPar(cc, myFirstPnt);
461 Standard_Real lpar = IntPar(cc, pt);
462 Handle(Geom_Curve) ccc;
464 ccc = Handle(Geom_Curve)::DownCast(cc->Reversed());
469 if(thePreviousEdge.IsNull()) {
470 BRepLib_MakeVertex v1(myFirstPnt);
471 BRepLib_MakeVertex v2(pt);
472 BRepLib_MakeEdge e(cc, v1, v2);
473 ee1 = TopoDS::Edge(e.Shape());
476 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
477 BRepLib_MakeVertex v2(pt);
479 BRepLib_MakeEdge e(cc, v1, v2);
480 ee1 = TopoDS::Edge(e.Shape());
482 TopoDS_Shape aLocalShape = ee1.Oriented(E.Orientation());
483 ee1 = TopoDS::Edge(aLocalShape);
484 // ee1 = TopoDS::Edge(ee1.Oriented(E.Orientation()));
485 if(counter == 1) theFV = TopExp::FirstVertex(ee1,Standard_True);
486 myLFMap(E).Append(ee1);
488 thePreviousEdge = ee1;
495 // Case of several edges
496 if(!FirstEdge.IsSame(LastEdge)) {
497 for(; EX1.More(); EX1.Next()) {
498 const TopoDS_Edge& E = EX1.Current();
499 if(!myLFMap.IsBound(E)) {
500 TopTools_ListOfShape thelist1;
501 myLFMap.Bind(E, thelist1);
505 if(!E.IsSame(LastEdge)) {
506 Handle(Geom_Curve) ccc = BRep_Tool::Curve(E, f, l);
507 TopoDS_Vertex v1, v2;
508 if(!thePreviousEdge.IsNull()) {
509 v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
510 v2 = TopExp::LastVertex(E,Standard_True);
513 // v1 = TopExp::LastVertex(E,Standard_True);
514 v1 = TopExp::FirstVertex(E,Standard_True);
515 v2 = TopExp::LastVertex(E,Standard_True);
517 BRepLib_MakeEdge E1(ccc, v1, v2);
518 TopoDS_Edge E11 = TopoDS::Edge(E1.Shape());
519 TopoDS_Shape aLocalShape = E11.Oriented(E.Orientation());
520 E11 = TopoDS::Edge(aLocalShape);
521 // E11 = TopoDS::Edge(E11.Oriented(E.Orientation()));
522 thePreviousEdge = E11;
523 myLFMap(E).Append(E11);
525 if(counter == 1) theFV = TopExp::FirstVertex(E11,Standard_True);
530 Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
531 gp_Pnt pf = BRep_Tool::Pnt(TopExp::FirstVertex(E,Standard_True));
532 gp_Pnt pl = myLastPnt;
534 if(thePreviousEdge.IsNull()) {
535 BRepLib_MakeEdge e(cc, pf , pl);
536 ee = TopoDS::Edge(e.Shape());
539 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
540 BRepLib_MakeVertex v2(pl);
541 BRepLib_MakeEdge e(cc, v1, v2);
542 ee = TopoDS::Edge(e.Shape());
544 TopoDS_Shape aLocalShape = ee.Oriented(E.Orientation());
545 ee = TopoDS::Edge(aLocalShape);
546 // ee = TopoDS::Edge(ee.Oriented(E.Orientation()));
548 myLFMap(E).Append(ee);
549 if(counter == 1) theFV = TopExp::FirstVertex(ee,Standard_True);
550 thePreviousEdge = ee;
557 TopTools_ListIteratorOfListOfShape it(myListOfEdges);
558 Standard_Boolean FirstOK = Standard_False;
559 Standard_Boolean LastOK = Standard_False;
561 gp_Pnt theLastPnt = myLastPnt;
562 Standard_Integer sens = 0;
563 TopoDS_Edge theEdge, theLEdge, theFEdge;
564 Standard_Integer counter1 = counter;
565 TopTools_ListOfShape NewListOfEdges;
566 NewListOfEdges.Clear();
568 const TopoDS_Edge& edg = TopoDS::Edge(it.Value());
571 Handle(Geom_Curve) ccc = BRep_Tool::Curve(edg, f, l);
572 Handle(Geom_TrimmedCurve) cc = new Geom_TrimmedCurve(ccc, f, l);
573 if ( edg.Orientation() == TopAbs_REVERSED) cc->Reverse();
575 fp = cc->Value(cc->FirstParameter());
576 lp = cc->Value(cc->LastParameter());
577 Standard_Real dist = fp.Distance(theLastPnt);
580 LastOK = Standard_True;
583 dist = lp.Distance(theLastPnt);
586 LastOK = Standard_True;
590 Standard_Integer FirstFlag = 0;
591 if(sens==1 && lp.Distance(myFirstPnt) <= myTol) {
592 FirstOK = Standard_True;
595 else if(sens==2 && fp.Distance(myFirstPnt) <= myTol) {
596 FirstOK = Standard_True;
602 Standard_Real fpar = cc->FirstParameter();
603 Standard_Real lpar = cc->LastParameter();
605 if(thePreviousEdge.IsNull()) {
606 BRepLib_MakeEdge e(cc, fpar, lpar);
607 eeee = TopoDS::Edge(e.Shape());
610 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
611 BB.UpdateVertex(v1, dist);
612 BRepLib_MakeVertex v2(cc->Value(lpar));
613 TopoDS_Vertex nv=v2.Vertex();
614 BRepLib_MakeEdge e(cc, v1, nv);
615 eeee = TopoDS::Edge(e.Shape());
619 if(thePreviousEdge.IsNull()) {
620 BRepLib_MakeVertex v1(cc->Value(fpar));
621 BRepLib_MakeEdge e(cc, v1, theFV);
622 eeee = TopoDS::Edge(e.Shape());
625 const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
626 BRepLib_MakeEdge e(cc, v1, theFV);
627 eeee = TopoDS::Edge(e.Shape());
631 thePreviousEdge = eeee;
633 if(counter == 1) theFV = TopExp::FirstVertex(eeee,Standard_True);
635 NewListOfEdges.Append(edg);
640 theLastPnt = BRep_Tool::Pnt(TopExp::LastVertex(theEdge,Standard_True));
646 else if(FirstFlag == 2) {
651 myListOfEdges.Remove(it);
652 it.Initialize(myListOfEdges);
653 LastOK = Standard_False;
655 else if(it.More()) it.Next();
657 Sliding = Standard_False;
664 TopTools_DataMapOfShapeListOfShape SlidMap;
667 if(Sliding && counter1 > counter) {
668 TopTools_ListIteratorOfListOfShape it;
669 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm;
670 TopExp_Explorer EX2(w, TopAbs_EDGE);
671 Standard_Integer ii = 0;
672 for(; EX2.More(); EX2.Next()) {
673 const TopoDS_Edge& E = TopoDS::Edge(EX2.Current());
675 if(ii >= counter && ii <= counter1) {
676 it.Initialize(NewListOfEdges);
677 Standard_Integer jj = 0;
678 for(; it.More(); it.Next()) {
679 const TopoDS_Edge& e2 = TopoDS::Edge(it.Value());
681 if(jj== (ii - counter +1)) {
682 itm.Initialize(mySlface);
683 for(; itm.More(); itm.Next()) {
684 const TopoDS_Face& fac = TopoDS::Face(itm.Key());
685 const TopTools_ListOfShape& ledg = itm.Value();
686 TopTools_ListIteratorOfListOfShape itedg(ledg);
687 //Standard_Integer iiii = 0;
688 for(; itedg.More(); itedg.Next()) {
689 const TopoDS_Edge& e1 = TopoDS::Edge(itedg.Value());
691 if(!SlidMap.IsBound(fac)) {
692 TopTools_ListOfShape thelist2;
693 SlidMap.Bind(fac, thelist2);
695 SlidMap(fac).Append(E);
709 // ---Arguments of LocOpe_LinearForm : arguments of the prism sliding
712 BB.MakeFace(F, myPln, myTol);
713 w.Closed (BRep_Tool::IsClosed (w));
715 // BRepLib_MakeFace F(myPln->Pln(),w, Standard_True);
722 // ---Case without sliding : construction of the profile face
726 if (Modify) cout << " Sliding failure" << endl;
727 cout << " no Sliding" << endl;
731 Standard_Boolean ProfileOK;
732 ProfileOK = NoSlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,
733 bnd,BndFace,CheckPnt,
734 FirstFace,LastFace,FirstVertex,LastVertex,
735 FirstEdge,LastEdge,OnFirstFace,OnLastFace);
741 cout << "Not computable" << endl;
742 cout << " Face profile not computable" << endl;
745 myStatusError = BRepFeat_NoFaceProf;
751 // ---Propagation on faces of the initial shape
752 // to find the faces concerned by the rib
753 Standard_Boolean falseside = Standard_True;
754 Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
755 // Control if there is everything required to have the material at the proper side
756 if(falseside == Standard_False) {
758 cout << "Verify plane and wire orientation" << endl;
760 myStatusError = BRepFeat_FalseSide;
767 TopTools_ListIteratorOfListOfShape it;
768 it.Initialize(SliList);
773 BB.MakeShell(TopoDS::Shell(comp));
775 for(; it.More(); it.Next()) {
776 BB.Add(comp, it.Value());
778 comp.Closed (BRep_Tool::IsClosed (comp));
789 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
790 TopTools_ListOfShape thelist3;
791 myMap.Bind(exp.Current(), thelist3);
792 myMap(exp.Current()).Append(exp.Current());
797 //=======================================================================
799 //purpose : add des element de collage
800 //=======================================================================
802 void BRepFeat_MakeLinearForm::Add(const TopoDS_Edge& E,
803 const TopoDS_Face& F)
806 Standard_Boolean trc = BRepFeat_GettraceFEAT();
807 if (trc) cout << "BRepFeat_MakeLinearForm::Add" << endl;
809 if(mySlface.IsEmpty()) {
811 for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
812 if (exp.Current().IsSame(F)) {
817 Standard_ConstructionError::Raise();
820 if (!mySlface.IsBound(F)) {
821 TopTools_ListOfShape thelist;
822 mySlface.Bind(F, thelist);
824 TopTools_ListIteratorOfListOfShape itl(mySlface(F));
825 for (; itl.More();itl.Next()) {
826 if (itl.Value().IsSame(E)) {
831 mySlface(F).Append(E);
838 //=======================================================================
840 //purpose : construction of rib from a profile and the initial shape
841 //=======================================================================
843 void BRepFeat_MakeLinearForm::Perform()
846 Standard_Boolean trc = BRepFeat_GettraceFEAT();
847 if (trc) cout << "BRepFeat_MakeLinearForm::Perform()" << endl;
849 if(mySbase.IsNull() || mySkface.IsNull() || myPbase.IsNull()) {
851 if (trc) cout << " Fields not initialized" << endl;
853 myStatusError = BRepFeat_NotInitialized;
858 gp_Vec nulldir(0, 0, 0);
860 Standard_Real Length = myDir.Magnitude() + myDir1.Magnitude();
864 if(!mySUntil.IsNull())
865 myPerfSelection = BRepFeat_SelectionU;
867 myPerfSelection = BRepFeat_NoSelection;
870 gp_Vec V = Length*dir;
872 LocOpe_LinearForm theForm;
874 if(myDir1.IsEqual(nulldir, Precision::Confusion(), Precision::Confusion()))
875 theForm.Perform(myPbase, V, myFirstPnt, myLastPnt);
877 theForm.Perform(myPbase, V, myDir1, myFirstPnt, myLastPnt);
879 TopoDS_Shape VraiForm = theForm.Shape(); // primitive of the rib
881 myFacesForDraft.Append(theForm.FirstShape());
882 myFacesForDraft.Append(theForm.LastShape());
883 MajMap(myPbase,theForm,myMap,myFShape,myLShape); // management of descendants
885 TopExp_Explorer exx(myPbase, TopAbs_EDGE);
886 for(; exx.More(); exx.Next()) {
887 const TopoDS_Edge& e = TopoDS::Edge(exx.Current());
888 if(!myMap.IsBound(e)) {
890 if (trc) cout << " Sliding face not in Base shape" << endl;
892 myStatusError = BRepFeat_IncSlidFace;
899 SetGluedFaces(mySlface, theForm, myGluedF); // management of sliding faces
901 if(!myGluedF.IsEmpty() && !mySUntil.IsNull()) {
905 cout << "The case is not computable" << endl;
906 cout << " Glued faces not empty and Until shape not null" << endl;
909 myStatusError = BRepFeat_InvShape;
918 TopExp_Explorer expr(mySbase, TopAbs_FACE);
919 char nom1[20], nom2[20];
920 Standard_Integer ii = 0;
921 for(; expr.More(); expr.Next()) {
923 sprintf(nom1, "faceinitial_%d", ii);
924 DBRep::Set(nom1, expr.Current());
925 Standard_Integer jj = 0;
926 const TopTools_ListOfShape& list = Modified(expr.Current());
927 TopTools_ListIteratorOfListOfShape ite(list);
928 for(; ite.More(); ite.Next()) {
930 sprintf(nom2, "facemodifie_%d_%d", ii, jj);
931 DBRep::Set(nom2, ite.Value());
935 expr.Init(myWire, TopAbs_EDGE);
937 for(; expr.More(); expr.Next()) {
939 sprintf(nom1, "edgeinitial_%d", ii);
940 DBRep::Set(nom1, expr.Current());
941 Standard_Integer jj = 0;
942 const TopTools_ListOfShape& genf = Generated(expr.Current());
943 TopTools_ListIteratorOfListOfShape ite(genf);
944 for(; ite.More(); ite.Next()) {
946 sprintf(nom2, "egdegeneree_%d_%d", ii, jj);
947 DBRep::Set(nom2, ite.Value());
953 //=======================================================================
954 //function : Propagate
955 //purpose : propagation on faces of the initial shape, find
956 // faces concerned by the rib
957 //=======================================================================
958 Standard_Boolean BRepFeat_MakeLinearForm::Propagate(TopTools_ListOfShape& SliList,
959 const TopoDS_Face& fac,
960 const gp_Pnt& Firstpnt,
961 const gp_Pnt& Lastpnt,
962 Standard_Boolean& falseside)
965 Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
966 if (trc) cout << "BRepFeat_MakeLinearForm::Propagate" << endl;
968 gp_Pnt Firstpoint = Firstpnt;
969 gp_Pnt Lastpoint = Lastpnt;
971 Standard_Boolean result = Standard_True;
972 TopoDS_Face CurrentFace, saveFace;
973 CurrentFace = TopoDS::Face(SliList.First());
974 saveFace = CurrentFace;
976 Standard_Boolean LastOK = Standard_False, FirstOK= Standard_False;
977 Standard_Boolean v1OK = Standard_False, v2OK= Standard_False;
978 TopoDS_Vertex v1, v2, v3, v4, ve1, ve2;
980 //modified by NIZNHY-PKV Fri Mar 22 16:50:24 2002 f
981 //BRepAlgo_Section sect (fac, CurrentFace, Standard_False);
982 BRepAlgoAPI_Section sect (fac, CurrentFace, Standard_False);
983 //modified by NIZNHY-PKV Fri Mar 22 16:50:32 2002 t
985 sect.Approximation(Standard_True);
991 Standard_Real t1 = 0., t2 = 0.;
992 Standard_Boolean c1f, c2f, c1l, c2l;
994 for (Ex.Init(sect.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
995 ec = TopoDS::Edge(Ex.Current());
996 v1 = TopExp::FirstVertex(ec,Standard_True);
997 v2 = TopExp::LastVertex(ec,Standard_True);
998 p1 = BRep_Tool::Pnt(v1);
999 p2 = BRep_Tool::Pnt(v2);
1000 t1 = BRep_Tool::Tolerance(v1);
1001 t2 = BRep_Tool::Tolerance(v2);
1002 c1f = p1.Distance(Firstpoint)<=t1;
1003 c2f = p2.Distance(Firstpoint)<=t2;
1004 c1l = p1.Distance(Lastpoint)<=t1;
1005 c2l = p2.Distance(Lastpoint)<=t2;
1006 if (c1f || c2f || c1l|| c2l) {
1008 if (c1f || c1l) v1OK=Standard_True;
1009 if (c2f || c2l) v2OK=Standard_True;
1010 if (c1f || c2f) FirstOK=Standard_True;
1011 if (c1l || c2l) LastOK=Standard_True;
1017 falseside = Standard_False;
1018 return Standard_False;
1020 TopTools_ListOfShape thelist;
1021 mySlface.Bind(CurrentFace, thelist);
1022 mySlface(CurrentFace).Append(eb);
1024 myListOfEdges.Clear();
1025 myListOfEdges.Append(eb);
1027 // two points are on the same face.
1028 if(LastOK && FirstOK) {
1032 TopTools_IndexedDataMapOfShapeListOfShape mapedges;
1033 TopExp::MapShapesAndAncestors(mySbase, TopAbs_EDGE, TopAbs_FACE, mapedges);
1035 TopoDS_Edge FirstEdge;
1038 TopoDS_Vertex Vprevious;
1042 while (!(LastOK && FirstOK)) {
1052 // find edge connected to v1 or v2:
1053 for (ex.Init(CurrentFace, TopAbs_EDGE); ex.More(); ex.Next()) {
1054 const TopoDS_Edge& rfe = TopoDS::Edge(ex.Current());
1056 BRepExtrema_ExtPC projF(Vprevious, rfe);
1058 if(projF.IsDone() && projF.NbExt() >=1) {
1059 Standard_Real dist2min = RealLast();
1060 Standard_Integer index = 0;
1061 for (Standard_Integer sol =1 ; sol <= projF.NbExt(); sol++) {
1062 if (projF.SquareDistance(sol) <= dist2min) {
1064 dist2min = projF.SquareDistance(sol);
1068 if (dist2min <= BRep_Tool::Tolerance(rfe) * BRep_Tool::Tolerance(rfe)) {
1070 // If the edge is not perpendicular to the plane of the rib
1071 // it is required to set Sliding(result) to false.
1073 result=Standard_False;
1074 ve1 = TopExp::FirstVertex(rfe,Standard_True);
1075 ve2 = TopExp::LastVertex(rfe,Standard_True);
1076 BRepExtrema_ExtPF perp(ve1, fac);
1077 if (perp.IsDone()) {
1078 gp_Pnt pe1=perp.Point(1);
1079 perp.Perform(ve2, fac);
1080 if (perp.IsDone()) {
1081 gp_Pnt pe2=perp.Point(1);
1082 if (pe1.Distance(pe2)<=BRep_Tool::Tolerance(rfe))
1083 result=Standard_True;
1093 const TopTools_ListOfShape& L = mapedges.FindFromKey(FirstEdge);
1094 TopTools_ListIteratorOfListOfShape It(L);
1096 for (; It.More(); It.Next()) {
1097 const TopoDS_Face& FF = TopoDS::Face(It.Value());
1098 if (!FF.IsSame(CurrentFace)) {
1104 //modified by NIZNHY-PKV Fri Mar 22 16:50:53 2002 f
1105 //BRepAlgo_Section sectf (fac, CurrentFace, Standard_False);
1106 BRepAlgoAPI_Section sectf (fac, CurrentFace, Standard_False);
1107 //modified by NIZNHY-PKV Fri Mar 22 16:51:03 2002 t
1108 sectf.Approximation(Standard_True);
1112 for (Ex.Init(sectf.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
1113 edg1 = TopoDS::Edge(Ex.Current());
1114 v1=TopExp::FirstVertex(edg1,Standard_True);
1115 v2=TopExp::LastVertex(edg1,Standard_True);
1116 t1 = BRep_Tool::Tolerance(v1);
1117 t2 = BRep_Tool::Tolerance(v2);
1118 p1 = BRep_Tool::Pnt(v1);
1119 p2 = BRep_Tool::Pnt(v2);
1120 v1OK = p1.Distance(ptprev)<=t1;
1121 v2OK = p2.Distance(ptprev)<=t2;
1122 if (v1OK || v2OK) break;
1127 dp = p2.Distance(Firstpoint);
1129 FirstOK = Standard_True;
1130 BB.UpdateVertex(v2, dp);
1134 dp = p2.Distance(Lastpoint);
1136 LastOK = Standard_True;
1137 BB.UpdateVertex(v2, dp);
1143 dp = p1.Distance(Firstpoint);
1145 FirstOK = Standard_True;
1146 BB.UpdateVertex(v1, dp);
1150 dp = p1.Distance(Lastpoint);
1152 LastOK = Standard_True;
1153 BB.UpdateVertex(v1, dp);
1158 // end by chaining the section
1159 return Standard_False;
1161 TopTools_ListOfShape thelist1;
1162 mySlface.Bind(CurrentFace, thelist1);
1163 mySlface(CurrentFace).Append(edg1);
1164 myListOfEdges.Append(edg1);
1171 //=======================================================================
1173 //purpose : management of descendants
1174 //=======================================================================
1176 static void MajMap(const TopoDS_Shape& theB,
1177 const LocOpe_LinearForm& theP,
1178 TopTools_DataMapOfShapeListOfShape& theMap, // myMap
1179 TopoDS_Shape& theFShape, // myFShape
1180 TopoDS_Shape& theLShape) // myLShape
1182 TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
1184 theFShape = exp.Current();
1185 TopTools_ListOfShape thelist;
1186 theMap.Bind(theFShape, thelist);
1187 for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
1188 theMap(theFShape).Append(exp.Current());
1192 exp.Init(theP.LastShape(),TopAbs_WIRE);
1194 theLShape = exp.Current();
1195 TopTools_ListOfShape thelist1;
1196 theMap.Bind(theLShape, thelist1);
1197 for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
1198 theMap(theLShape).Append(exp.Current());
1202 for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
1203 if (!theMap.IsBound(exp.Current())) {
1204 TopTools_ListOfShape thelist2;
1205 theMap.Bind(exp.Current(), thelist2);
1206 theMap(exp.Current()) = theP.Shapes(exp.Current());
1211 //=======================================================================
1212 //function : SetGluedFaces
1213 //purpose : management of faces of gluing
1214 //=======================================================================
1216 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
1217 LocOpe_LinearForm& thePrism,
1218 TopTools_DataMapOfShapeShape& theMap)
1221 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(theSlmap);
1222 if(!theSlmap.IsEmpty()) {
1223 for (; itm.More(); itm.Next()) {
1224 const TopoDS_Face& fac = TopoDS::Face(itm.Key());
1225 const TopTools_ListOfShape& ledg = itm.Value();
1226 TopTools_ListIteratorOfListOfShape it;
1227 for (it.Initialize(ledg); it.More(); it.Next()) {
1228 const TopTools_ListOfShape& gfac = thePrism.Shapes(it.Value());
1229 if (gfac.Extent() != 1) {
1231 cout << "Pb SetGluedFace" << endl;
1234 theMap.Bind(gfac.First(),fac);