0024510: Remove unused local variables
[occt.git] / src / BRepFeat / BRepFeat_MakeLinearForm.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public 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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <BRepFeat_MakeLinearForm.ixx>
18
19 #include <BRepFeat.hxx>
20
21 #include <LocOpe.hxx>
22 #include <LocOpe_LinearForm.hxx>
23 #include <LocOpe_Gluer.hxx>
24 #include <LocOpe_FindEdges.hxx>
25
26 #include <gp_Vec.hxx>
27 #include <gp_Pln.hxx>
28 #include <gp_Lin.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Pnt.hxx>
31
32 #include <gp_Vec2d.hxx>
33 #include <gp_Pnt2d.hxx>
34
35 #include <Geom_Curve.hxx>
36
37 #include <Geom2d_Curve.hxx>
38 #include <Geom2d_Line.hxx>
39
40 #include <Geom_Plane.hxx>
41 #include <Geom_Surface.hxx>
42 #include <Geom_CylindricalSurface.hxx>
43 #include <Geom_RectangularTrimmedSurface.hxx>
44
45 #include <Geom_TrimmedCurve.hxx>
46 #include <GeomProjLib.hxx>
47
48 #include <Geom2d_Curve.hxx>
49 #include <Geom2d_Curve.hxx>
50
51 #include <TColgp_SequenceOfPnt.hxx>
52
53 #include <TColStd_Array1OfReal.hxx>
54 #include <IntRes2d_IntersectionPoint.hxx>
55
56 #include <BRepTools_WireExplorer.hxx>
57
58 #include <BRep_Tool.hxx>
59 #include <BRep_Builder.hxx>
60
61 #include <TopExp_Explorer.hxx>
62 #include <TopExp.hxx>
63
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>
72
73 #include <TColgp_Array1OfPnt.hxx>
74
75 #include <TColGeom_Array1OfCurve.hxx>
76
77 #include <TopoDS.hxx>
78 #include <TopoDS_Shape.hxx>
79 #include <TopoDS_Face.hxx>
80
81 #include <BRepLib_MakeVertex.hxx>
82 #include <BRepLib_MakeEdge.hxx>
83 #include <BRepLib_MakeFace.hxx>
84
85 #include <BRepTools.hxx>
86
87 #include <BRepBuilderAPI.hxx>
88 #include <BRepPrimAPI_MakeBox.hxx>
89 #include <BRepBuilderAPI_MakeFace.hxx>
90
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
97
98 #include <BRepExtrema_ExtPC.hxx>
99 #include <BRepExtrema_ExtPF.hxx>
100 #include <BRepExtrema_ExtCF.hxx>
101
102 #include <BRepTools_Modifier.hxx>
103 #include <BRepTools_TrsfModification.hxx>
104
105 #include <Standard_ConstructionError.hxx>
106
107 #include <Precision.hxx>
108
109 #include <GeomLProp_CLProps.hxx>
110
111 #include <BRepBuilderAPI_Transform.hxx>
112 #include <BRepLib_MakeWire.hxx>
113 //#include <DbgTools.hxx>
114
115 #ifdef DEB
116 extern Standard_Boolean BRepFeat_GettraceFEAT();
117 extern Standard_Boolean BRepFeat_GettraceFEATRIB();
118 #endif
119
120 static void MajMap(const TopoDS_Shape&, // base
121                    const LocOpe_LinearForm&,
122                    TopTools_DataMapOfShapeListOfShape&, // myMap
123                    TopoDS_Shape&,  // myFShape
124                    TopoDS_Shape&); // myLShape
125
126 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
127                           LocOpe_LinearForm&,
128                           TopTools_DataMapOfShapeShape&);
129
130 //=======================================================================
131 //function : Init
132 //purpose  : 
133 //=======================================================================
134
135 void BRepFeat_MakeLinearForm::Init(const TopoDS_Shape& Sbase,
136                                    const TopoDS_Wire& W,
137                                    const Handle(Geom_Plane)& Plane,
138                                    const gp_Vec& Direc,
139                                    const gp_Vec& Direc1,
140                                    const Standard_Integer Mode,
141                                    const Standard_Boolean Modify)
142 {
143 #ifdef DEB
144   Standard_Boolean trc = BRepFeat_GettraceFEAT();
145   if (trc) cout << "BRepFeat_MakeLinearForm::Init" << endl;
146 #endif
147   Standard_Boolean RevolRib = Standard_False;
148   Done();
149   myGenerated.Clear();
150   
151 // modify = 0 if there is no intention to make sliding
152 //        = 1 if one tries to make sliding
153   Standard_Boolean Sliding = Modify;
154   myLFMap.Clear();
155
156   myShape.Nullify();
157   myMap.Clear();
158   myFShape.Nullify();
159   myLShape.Nullify();
160   mySbase  = Sbase;
161   mySkface.Nullify();
162   myPbase.Nullify();
163
164   myGShape.Nullify();
165   mySUntil.Nullify();
166   myListOfEdges.Clear();
167   mySlface.Clear();
168
169   TopoDS_Shape aLocalShape = W.Oriented(TopAbs_FORWARD);
170   myWire = TopoDS::Wire(aLocalShape);
171 //  myWire = TopoDS::Wire(W.Oriented(TopAbs_FORWARD));
172   myDir  = Direc;
173   myDir1 = Direc1;
174   myPln  = Plane;
175
176   if(Mode == 0) 
177     myFuse   = Standard_False;
178   else // if(Mode == 1) 
179     myFuse   = Standard_True;
180 #ifdef DEB
181   if (trc) {
182     if (myFuse)  cout << " Fuse" << endl;
183     if (!myFuse)  cout << " Cut" << endl;
184   }
185 #endif
186
187   
188 // ---Determine Tolerance : max tolerance on parameters
189   myTol = Precision::Confusion();
190
191   TopExp_Explorer exx;  
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;
197   }
198
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;
204   }
205
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);
211     if(ang != M_PI) {
212 #ifdef DEB
213       if (trc) cout << " Directions must be opposite" << endl;
214 #endif
215       myStatusError = BRepFeat_BadDirect;
216       NotDone();
217       return;
218     }
219   }
220   else {
221
222 // Rib is centre in the middle of translation
223 #ifdef DEB
224     if (trc)  cout << " Rib is centre" << endl;
225 #endif
226     const gp_Vec& DirTranslation = (Direc + Direc1) * 0.5;
227     gp_Trsf T;
228     T.SetTranslation(DirTranslation);
229     BRepBuilderAPI_Transform trf(T);
230     trf.Perform(myWire);
231     myWire = TopoDS::Wire(trf.Shape());
232     myDir  = Direc  - DirTranslation;
233     myDir1 = Direc1 - DirTranslation;
234     myPln->Transform(T);
235   }
236
237 // ---Calculate bounding box
238   BRep_Builder BB;
239
240   TopTools_ListOfShape theList;  
241   
242   TopoDS_Shape U;
243   U.Nullify();
244   gp_Pnt FirstCorner, LastCorner;
245   Standard_Real bnd = HeightMax(mySbase, U, FirstCorner, LastCorner);
246   myBnd = bnd;
247
248   BRepPrimAPI_MakeBox Bndbox(FirstCorner, LastCorner);
249   TopoDS_Solid BndBox = Bndbox.Solid();
250
251
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());
256
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  
261   TopExp_Explorer EXP;
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());
267
268
269 // ---Find support faces of the rib
270   TopoDS_Edge FirstEdge, LastEdge;
271   TopoDS_Face FirstFace, LastFace;
272   TopoDS_Vertex FirstVertex, LastVertex;
273
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();
281
282   Standard_Boolean Data = ExtremeFaces(RevolRib, myBnd, myPln, FirstEdge, LastEdge, 
283                                        FirstFace, LastFace, FirstVertex, 
284                                        LastVertex, OnFirstFace, OnLastFace,
285                                        PtOnFirstEdge, PtOnLastEdge,
286                                        OnFirstEdge, OnLastEdge);
287  
288   if(!Data) {
289 #ifdef DEB
290     if (trc) cout << " No Extreme faces" << endl;
291 #endif
292     myStatusError = BRepFeat_NoExtFace;
293     NotDone();
294     return;
295   }
296
297
298 // ---Proofing Point for the side of the wire to be filled - side material
299   gp_Pnt CheckPnt = CheckPoint(FirstEdge, bnd/10., myPln);
300
301 //  Standard_Real f, l;
302
303 // ---Control sliding valuable
304 // Many cases when the sliding is abandoned
305   Standard_Integer Concavite = 3;  // a priori the profile is not concave
306
307   myFirstPnt = BRep_Tool::Pnt(FirstVertex);
308   myLastPnt  = BRep_Tool::Pnt(LastVertex);
309
310 // SliList : list of faces concerned by the rib
311   TopTools_ListOfShape SliList;
312   SliList.Append(FirstFace);
313
314   if(Sliding) {    // sliding
315 #ifdef DEB
316     if (trc) cout << " Sliding" << endl;
317 #endif
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();
324     }
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;
329     }
330   }
331
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
336   if(Sliding) {
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;
348       }
349       else {
350         Sliding = Standard_False;
351       }      
352     }
353     else {
354       Sliding = Standard_False;
355     }   
356   }
357
358   if(!myDir1.IsEqual(nulldir, Precision::Confusion(), Precision::Confusion())) {
359     if(Sliding) {
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;
371         }
372         else {
373           Sliding = Standard_False;
374         }      
375       }
376       else {
377         Sliding = Standard_False;
378       }   
379     }
380   }
381
382
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
387
388
389 // ---case of sliding : construction of the profile face 
390   if(Sliding) {
391 #ifdef DEB
392     if (trc) cout << " still Sliding" << endl;
393 #endif
394     TopoDS_Face Prof;
395     Standard_Boolean ProfileOK;
396     ProfileOK = SlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,BndFace,CheckPnt,
397                                FirstFace,LastFace,FirstVertex,LastVertex,
398                                FirstEdge,LastEdge);
399     
400     if (!ProfileOK) {
401 #ifdef DEB
402       cout << "Not computable" << endl;
403       if (trc) cout << "Face profile not computable" << endl;
404 #endif
405       myStatusError = BRepFeat_NoFaceProf;
406       NotDone();
407       return;
408     }
409
410
411 // ---Propagation on faces of the initial shape 
412 // to find the faces concerned by the rib
413     Standard_Boolean falseside = Standard_True;
414     Sliding = Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
415 // Control if there is everything required to have the material at the proper side
416     if(falseside == Standard_False) {
417 #ifdef DEB
418       cout << "Verify plane and wire orientation" << endl;
419 #endif
420       myStatusError = BRepFeat_FalseSide;
421       NotDone();
422       return;
423     }
424   }
425
426
427 // ---Generation of the base of the rib profile 
428
429   TopoDS_Wire w;
430   BB.MakeWire(w);
431   TopoDS_Edge thePreviousEdge;
432   TopoDS_Vertex theFV;
433   thePreviousEdge.Nullify();
434
435 // calculate the number of edges to fill the map
436   Standard_Integer counter = 1;
437
438 // ---case of sliding
439   if(Sliding && !myListOfEdges.IsEmpty()) {
440     BRepTools_WireExplorer EX1(myWire);
441     for(; EX1.More(); EX1.Next()) {
442       const TopoDS_Edge& E = EX1.Current();
443       if(!myLFMap.IsBound(E)) {
444         TopTools_ListOfShape theTmpList;
445         myLFMap.Bind(E, theTmpList );
446       }      
447       if(E.IsSame(FirstEdge)) {
448         Standard_Real f, l;
449         Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
450         cc = new Geom_TrimmedCurve(cc, f, l);
451         gp_Pnt pt;
452         if(!FirstEdge.IsSame(LastEdge)) {
453           pt = BRep_Tool::Pnt(TopExp::LastVertex(E,Standard_True)); 
454         }
455         else {
456           pt = myLastPnt;
457           Standard_Real fpar = IntPar(cc, myFirstPnt);
458           Standard_Real lpar = IntPar(cc, pt);
459           Handle(Geom_Curve) ccc;
460           if(fpar > lpar) {
461             ccc = Handle(Geom_Curve)::DownCast(cc->Reversed());
462             cc = ccc;
463           }
464         }
465         TopoDS_Edge ee1;
466         if(thePreviousEdge.IsNull()) {
467           BRepLib_MakeVertex v1(myFirstPnt);
468           BRepLib_MakeVertex v2(pt);      
469           BRepLib_MakeEdge e(cc, v1, v2);
470           ee1 = TopoDS::Edge(e.Shape());
471         } 
472         else {
473           const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
474           BRepLib_MakeVertex v2(pt);
475           
476           BRepLib_MakeEdge e(cc, v1, v2);
477           ee1 = TopoDS::Edge(e.Shape());
478         }
479         TopoDS_Shape aLocalShape = ee1.Oriented(E.Orientation());
480         ee1 = TopoDS::Edge(aLocalShape);
481 //      ee1 = TopoDS::Edge(ee1.Oriented(E.Orientation()));
482         if(counter == 1) theFV = TopExp::FirstVertex(ee1,Standard_True);
483         myLFMap(E).Append(ee1);
484         BB.Add(w, ee1);
485         thePreviousEdge = ee1;
486         counter++;
487         EX1.Next();
488         break;
489       }
490     }
491  
492 // Case of several edges
493     if(!FirstEdge.IsSame(LastEdge)) {
494       for(; EX1.More(); EX1.Next()) {
495         const TopoDS_Edge& E = EX1.Current();
496         if(!myLFMap.IsBound(E)) {
497           TopTools_ListOfShape thelist1;
498           myLFMap.Bind(E, thelist1);
499         }      
500         theList.Append(E);
501         Standard_Real f, l;
502         if(!E.IsSame(LastEdge)) {
503           Handle(Geom_Curve) ccc = BRep_Tool::Curve(E, f, l);
504           TopoDS_Vertex v1, v2;
505           if(!thePreviousEdge.IsNull()) {
506             v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
507             v2 = TopExp::LastVertex(E,Standard_True);
508           }
509           else {
510 //          v1 = TopExp::LastVertex(E,Standard_True);
511             v1 = TopExp::FirstVertex(E,Standard_True);
512             v2 = TopExp::LastVertex(E,Standard_True);
513           }
514           BRepLib_MakeEdge E1(ccc, v1, v2);
515           TopoDS_Edge E11 = TopoDS::Edge(E1.Shape());
516           TopoDS_Shape aLocalShape = E11.Oriented(E.Orientation());
517           E11 = TopoDS::Edge(aLocalShape);
518 //        E11 = TopoDS::Edge(E11.Oriented(E.Orientation()));
519           thePreviousEdge = E11;
520           myLFMap(E).Append(E11);
521           BB.Add(w, E11);
522           if(counter == 1) theFV = TopExp::FirstVertex(E11,Standard_True);
523           counter++;
524         }
525         else {
526           Standard_Real f, l;
527           Handle(Geom_Curve) cc = BRep_Tool::Curve(E, f, l);
528           gp_Pnt pf = BRep_Tool::Pnt(TopExp::FirstVertex(E,Standard_True));
529           gp_Pnt pl = myLastPnt;
530           TopoDS_Edge ee;
531           if(thePreviousEdge.IsNull()) {
532             BRepLib_MakeEdge e(cc, pf , pl); 
533             ee = TopoDS::Edge(e.Shape());
534           }
535           else {
536             const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
537             BRepLib_MakeVertex v2(pl);
538             BRepLib_MakeEdge e(cc, v1, v2);
539             ee = TopoDS::Edge(e.Shape());
540           }
541           TopoDS_Shape aLocalShape = ee.Oriented(E.Orientation());
542           ee = TopoDS::Edge(aLocalShape);
543 //        ee = TopoDS::Edge(ee.Oriented(E.Orientation()));
544           BB.Add(w, ee);
545           myLFMap(E).Append(ee);
546           if(counter == 1) theFV = TopExp::FirstVertex(ee,Standard_True);
547           thePreviousEdge = ee;
548           counter++;
549           break;
550         }
551       }
552     }
553     
554     TopTools_ListIteratorOfListOfShape it(myListOfEdges);
555     Standard_Boolean FirstOK = Standard_False;
556     Standard_Boolean LastOK = Standard_False;
557     
558     gp_Pnt theLastPnt = myLastPnt;
559     Standard_Integer sens = 0;
560     TopoDS_Edge theEdge, theLEdge, theFEdge;
561     Standard_Integer counter1 = counter;
562     TopTools_ListOfShape NewListOfEdges;
563     NewListOfEdges.Clear();
564     while (!FirstOK) {
565       const TopoDS_Edge& edg = TopoDS::Edge(it.Value());
566       gp_Pnt fp, lp;
567       Standard_Real f, l;
568       Handle(Geom_Curve) ccc = BRep_Tool::Curve(edg, f, l);
569       Handle(Geom_TrimmedCurve) cc = new Geom_TrimmedCurve(ccc, f, l);
570       if ( edg.Orientation() == TopAbs_REVERSED) cc->Reverse();
571
572       fp = cc->Value(cc->FirstParameter());
573       lp = cc->Value(cc->LastParameter());
574       Standard_Real dist = fp.Distance(theLastPnt);
575       if(dist <= myTol) {
576         sens = 1;
577         LastOK = Standard_True;
578       }
579       else {
580         dist = lp.Distance(theLastPnt);
581         if(dist <= myTol) {
582           sens = 2;
583           LastOK = Standard_True;
584           cc->Reverse();
585         }
586       }
587       Standard_Integer FirstFlag = 0;
588       if(sens==1 && lp.Distance(myFirstPnt) <= myTol) {
589         FirstOK = Standard_True;
590         FirstFlag = 1;
591       }
592       else if(sens==2 && fp.Distance(myFirstPnt) <= myTol) {
593         FirstOK = Standard_True;
594         FirstFlag = 2;
595       }
596       
597       if (LastOK) {
598         TopoDS_Edge eeee;
599         Standard_Real fpar = cc->FirstParameter();
600         Standard_Real lpar = cc->LastParameter();
601         if(!FirstOK) {
602           if(thePreviousEdge.IsNull()) {
603             BRepLib_MakeEdge e(cc, fpar, lpar);
604             eeee = TopoDS::Edge(e.Shape());
605           }
606           else {
607             const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
608             BB.UpdateVertex(v1, dist);
609             BRepLib_MakeVertex v2(cc->Value(lpar));
610             TopoDS_Vertex nv=v2.Vertex();
611             BRepLib_MakeEdge e(cc, v1, nv);
612             eeee = TopoDS::Edge(e.Shape());
613           }
614         }
615         else {
616           if(thePreviousEdge.IsNull()) {
617             BRepLib_MakeVertex v1(cc->Value(fpar)); 
618             BRepLib_MakeEdge e(cc, v1, theFV);
619             eeee = TopoDS::Edge(e.Shape());
620           }
621           else {
622             const TopoDS_Vertex& v1 = TopExp::LastVertex(thePreviousEdge,Standard_True);
623             BRepLib_MakeEdge e(cc, v1, theFV);
624             eeee = TopoDS::Edge(e.Shape());
625           }
626         }
627
628         thePreviousEdge = eeee;
629         BB.Add(w, eeee);
630         if(counter == 1) theFV = TopExp::FirstVertex(eeee,Standard_True);
631         counter1++;
632         NewListOfEdges.Append(edg);
633         theEdge = eeee;
634
635         if(dist <= myTol) 
636           theFEdge = edg;
637         theLastPnt = BRep_Tool::Pnt(TopExp::LastVertex(theEdge,Standard_True));
638       }
639
640       if(FirstFlag == 1) {
641         theLEdge = edg;
642       }
643       else if(FirstFlag == 2) {
644         theLEdge = theEdge;
645       }
646
647       if(LastOK) {
648         myListOfEdges.Remove(it);
649         it.Initialize(myListOfEdges);
650         LastOK = Standard_False;
651       }
652       else if(it.More()) it.Next();
653       else {
654         Sliding = Standard_False;
655         break;
656       } 
657       sens = 0;
658     }
659
660
661     TopTools_DataMapOfShapeListOfShape SlidMap;
662     SlidMap.Clear();
663     
664     if(Sliding && counter1 > counter) {
665       TopTools_ListIteratorOfListOfShape it;
666       TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm;
667       TopExp_Explorer EX2(w, TopAbs_EDGE);
668       Standard_Integer ii = 0;
669       for(; EX2.More(); EX2.Next()) {
670         const TopoDS_Edge& E = TopoDS::Edge(EX2.Current());
671         ii++;   
672         if(ii >= counter && ii <= counter1) {
673           it.Initialize(NewListOfEdges);
674           Standard_Integer jj = 0;
675           for(; it.More(); it.Next()) {
676             const TopoDS_Edge& e2 = TopoDS::Edge(it.Value());
677             jj++;
678             if(jj== (ii - counter +1)) {          
679               itm.Initialize(mySlface);
680               for(; itm.More(); itm.Next()) {
681                 const TopoDS_Face& fac = TopoDS::Face(itm.Key());
682                 const TopTools_ListOfShape& ledg = itm.Value();
683                 TopTools_ListIteratorOfListOfShape itedg(ledg);
684                 //Standard_Integer iiii = 0;
685                 for(; itedg.More(); itedg.Next()) {
686                   const TopoDS_Edge& e1 = TopoDS::Edge(itedg.Value());
687                   if(e1.IsSame(e2)){
688                     if(!SlidMap.IsBound(fac)) {
689                       TopTools_ListOfShape thelist2;
690                       SlidMap.Bind(fac, thelist2);
691                     }
692                     SlidMap(fac).Append(E);
693                   }
694                 }               
695               }
696             }
697           } 
698         }
699       }
700     }
701
702     mySlface.Clear();
703     mySlface = SlidMap;
704   }
705
706 // ---Arguments of LocOpe_LinearForm : arguments of the prism sliding
707   if(Sliding) {
708     TopoDS_Face F;
709     BB.MakeFace(F, myPln, myTol);
710     BB.Add(F, w);
711 //    BRepLib_MakeFace F(myPln->Pln(),w, Standard_True);
712     mySkface = F;
713     myPbase  = mySkface;
714     mySUntil.Nullify();
715   }
716   
717
718 // ---Case without sliding : construction of the profile face   
719   if(!Sliding) {
720 #ifdef DEB
721     if (trc) {
722       if (Modify) cout << " Sliding failure" << endl;
723       cout << " no Sliding" << endl;
724     }
725 #endif
726     TopoDS_Face Prof;
727     Standard_Boolean ProfileOK;
728     ProfileOK = NoSlidingProfile(Prof,RevolRib,myTol,Concavite,myPln,
729                                  bnd,BndFace,CheckPnt,
730                                  FirstFace,LastFace,FirstVertex,LastVertex,
731                                  FirstEdge,LastEdge,OnFirstFace,OnLastFace);
732     
733     if (!ProfileOK) {
734 #ifdef DEB
735       cout << "Not computable" << endl;
736       if (trc) cout << " Face profile not computable" << endl;
737 #endif
738       myStatusError = BRepFeat_NoFaceProf;
739       NotDone();
740       return;
741     }
742
743
744 // ---Propagation on faces of the initial shape
745 // to find the faces concerned by the rib
746     Standard_Boolean falseside = Standard_True;
747     Propagate(SliList, Prof, myFirstPnt, myLastPnt, falseside);
748 // Control if there is everything required to have the material at the proper side
749     if(falseside == Standard_False) {
750 #ifdef DEB
751       cout << "Verify plane and wire orientation" << endl;
752 #endif
753       myStatusError = BRepFeat_FalseSide;
754       NotDone();
755       return;
756     }
757
758     mySlface.Clear();
759
760     TopTools_ListIteratorOfListOfShape it;
761     it.Initialize(SliList);
762     
763     TopoDS_Shape comp;
764     
765     BRep_Builder BB;
766     BB.MakeShell(TopoDS::Shell(comp));
767     
768     for(; it.More(); it.Next()) {
769       BB.Add(comp, it.Value());
770     }
771     
772     mySUntil = comp;
773
774     mySkface = Prof;
775     myPbase  = Prof;
776   }
777
778   mySliding = Sliding;
779
780   TopExp_Explorer exp;
781   for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
782     TopTools_ListOfShape thelist3;
783     myMap.Bind(exp.Current(), thelist3);
784     myMap(exp.Current()).Append(exp.Current());
785   }
786 }
787
788
789 //=======================================================================
790 //function : Add
791 //purpose  : add des element de collage
792 //=======================================================================
793
794 void BRepFeat_MakeLinearForm::Add(const TopoDS_Edge& E,
795                                   const TopoDS_Face& F)
796 {
797 #ifdef DEB
798   Standard_Boolean trc = BRepFeat_GettraceFEAT();
799   if (trc) cout << "BRepFeat_MakeLinearForm::Add" << endl;
800 #endif
801   if(mySlface.IsEmpty()) {
802     TopExp_Explorer exp;
803     for (exp.Init(mySbase,TopAbs_FACE);exp.More();exp.Next()) {
804       if (exp.Current().IsSame(F)) {
805         break;
806       }
807     }
808     if (!exp.More()) {
809       Standard_ConstructionError::Raise();
810     }
811   
812     if (!mySlface.IsBound(F)) {
813       TopTools_ListOfShape thelist;
814       mySlface.Bind(F, thelist);
815     }
816     TopTools_ListIteratorOfListOfShape itl(mySlface(F));
817     for (; itl.More();itl.Next()) {
818       if (itl.Value().IsSame(E)) {
819         break;
820       }
821     }
822     if (!itl.More()) {
823       mySlface(F).Append(E);
824     }
825   } 
826 }
827
828   
829
830 //=======================================================================
831 //function : Perform
832 //purpose  : construction of rib from a profile and the initial shape
833 //=======================================================================
834
835 void BRepFeat_MakeLinearForm::Perform()
836 {
837 #ifdef DEB
838   Standard_Boolean trc = BRepFeat_GettraceFEAT();
839   if (trc) cout << "BRepFeat_MakeLinearForm::Perform()" << endl;
840 #endif
841   if(mySbase.IsNull() || mySkface.IsNull() || myPbase.IsNull()) {
842 #ifdef DEB
843     if (trc) cout << " Fields not initialized" << endl;
844 #endif
845     myStatusError = BRepFeat_NotInitialized;
846     NotDone();
847     return;
848   }
849
850   gp_Vec nulldir(0, 0, 0);
851
852   Standard_Real Length = myDir.Magnitude() +  myDir1.Magnitude();
853
854   myGluedF.Clear();
855  
856   if(!mySUntil.IsNull()) 
857     myPerfSelection = BRepFeat_SelectionU;
858   else 
859     myPerfSelection = BRepFeat_NoSelection;
860
861   gp_Dir dir(myDir);
862   gp_Vec V = Length*dir;
863
864   LocOpe_LinearForm theForm;
865
866   if(myDir1.IsEqual(nulldir, Precision::Confusion(), Precision::Confusion())) 
867     theForm.Perform(myPbase, V, myFirstPnt, myLastPnt);
868   else 
869     theForm.Perform(myPbase, V, myDir1, myFirstPnt, myLastPnt);
870
871   TopoDS_Shape VraiForm = theForm.Shape();   // primitive of the rib
872
873   myFacesForDraft.Append(theForm.FirstShape());
874   myFacesForDraft.Append(theForm.LastShape());
875   MajMap(myPbase,theForm,myMap,myFShape,myLShape);   // management of descendants
876
877   TopExp_Explorer exx(myPbase, TopAbs_EDGE);
878   for(; exx.More(); exx.Next()) {
879     const TopoDS_Edge& e = TopoDS::Edge(exx.Current());
880     if(!myMap.IsBound(e)) {
881 #ifdef DEB
882       if (trc) cout << " Sliding face not in Base shape" << endl;
883 #endif
884       myStatusError = BRepFeat_IncSlidFace;
885       NotDone();
886       return;
887     }
888   }
889
890   myGShape = VraiForm;
891   SetGluedFaces(mySlface, theForm, myGluedF);  // management of sliding faces  
892
893   if(!myGluedF.IsEmpty() && !mySUntil.IsNull()) {
894 #ifdef DEB
895     cout << "The case is not computable" << endl;
896     if (trc) cout << " Glued faces not empty and Until shape not null" << endl;
897 #endif
898     myStatusError = BRepFeat_InvShape;
899     NotDone();
900     return;
901   }
902
903   LFPerform();
904
905 /*
906
907   TopExp_Explorer expr(mySbase, TopAbs_FACE);
908   char nom1[20], nom2[20];
909   Standard_Integer ii = 0;
910   for(; expr.More(); expr.Next()) {
911     ii++;
912     sprintf(nom1, "faceinitial_%d", ii);
913     DBRep::Set(nom1, expr.Current());
914     Standard_Integer jj = 0;
915     const TopTools_ListOfShape& list = Modified(expr.Current());
916     TopTools_ListIteratorOfListOfShape ite(list);
917     for(; ite.More(); ite.Next()) {
918       jj++;
919       sprintf(nom2, "facemodifie_%d_%d", ii, jj);
920       DBRep::Set(nom2, ite.Value());
921     }
922   }
923
924   expr.Init(myWire, TopAbs_EDGE);
925   ii=0;
926   for(; expr.More(); expr.Next()) {
927     ii++;
928     sprintf(nom1, "edgeinitial_%d", ii);
929     DBRep::Set(nom1, expr.Current());
930     Standard_Integer jj = 0;
931     const TopTools_ListOfShape& genf = Generated(expr.Current());
932     TopTools_ListIteratorOfListOfShape ite(genf);
933     for(; ite.More(); ite.Next()) {
934       jj++;
935       sprintf(nom2, "egdegeneree_%d_%d", ii, jj);
936       DBRep::Set(nom2, ite.Value());
937     }
938   }
939 */
940 }
941
942 //=======================================================================
943 //function : Propagate
944 //purpose  : propagation on faces of the initial shape, find 
945 // faces concerned by the rib
946 //=======================================================================
947   Standard_Boolean BRepFeat_MakeLinearForm::Propagate(TopTools_ListOfShape& SliList,
948                                                       const TopoDS_Face& fac,
949                                                       const gp_Pnt& Firstpnt, 
950                                                       const gp_Pnt& Lastpnt, 
951                                                       Standard_Boolean& falseside)
952 {
953 #ifdef DEB
954   Standard_Boolean trc = BRepFeat_GettraceFEATRIB();
955   if (trc) cout << "BRepFeat_MakeLinearForm::Propagate" << endl;
956 #endif
957   gp_Pnt Firstpoint = Firstpnt;
958   gp_Pnt Lastpoint = Lastpnt;
959
960   Standard_Boolean result = Standard_True;
961   TopoDS_Face CurrentFace, saveFace;
962   CurrentFace = TopoDS::Face(SliList.First());
963   saveFace = CurrentFace;
964
965   Standard_Boolean LastOK = Standard_False, FirstOK= Standard_False;
966   Standard_Boolean v1OK = Standard_False, v2OK= Standard_False;
967   TopoDS_Vertex v1, v2, v3, v4, ve1, ve2;
968
969   //modified by NIZNHY-PKV Fri Mar 22 16:50:24 2002 f
970   //BRepAlgo_Section sect (fac, CurrentFace, Standard_False);
971   BRepAlgoAPI_Section sect (fac, CurrentFace, Standard_False);
972   //modified by NIZNHY-PKV Fri Mar 22 16:50:32 2002 t
973
974   sect.Approximation(Standard_True);
975   sect.Build();
976
977   TopExp_Explorer Ex;
978   TopoDS_Edge eb, ec;
979   gp_Pnt p1, p2;
980   Standard_Real t1 = 0., t2 = 0.;
981   Standard_Boolean c1f, c2f, c1l, c2l;
982
983   for (Ex.Init(sect.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
984     ec = TopoDS::Edge(Ex.Current());
985     v1 = TopExp::FirstVertex(ec,Standard_True); 
986     v2 = TopExp::LastVertex(ec,Standard_True); 
987     p1 = BRep_Tool::Pnt(v1);
988     p2 = BRep_Tool::Pnt(v2);
989     t1 = BRep_Tool::Tolerance(v1);
990     t2 = BRep_Tool::Tolerance(v2);
991     c1f = p1.Distance(Firstpoint)<=t1;
992     c2f = p2.Distance(Firstpoint)<=t2;
993     c1l = p1.Distance(Lastpoint)<=t1;
994     c2l = p2.Distance(Lastpoint)<=t2;
995     if (c1f || c2f || c1l|| c2l) {
996       eb = ec;
997       if (c1f || c1l) v1OK=Standard_True;
998       if (c2f || c2l) v2OK=Standard_True;
999       if (c1f || c2f) FirstOK=Standard_True;
1000       if (c1l || c2l) LastOK=Standard_True;
1001       break;
1002     }
1003   }
1004
1005   if(eb.IsNull()) {
1006     falseside = Standard_False;
1007     return Standard_False;
1008   }
1009   TopTools_ListOfShape thelist;
1010   mySlface.Bind(CurrentFace, thelist);
1011   mySlface(CurrentFace).Append(eb);
1012     
1013   myListOfEdges.Clear();
1014   myListOfEdges.Append(eb);
1015     
1016   // two points are on the same face.
1017   if(LastOK && FirstOK) {
1018     return result;
1019   }
1020   
1021   TopTools_IndexedDataMapOfShapeListOfShape mapedges;
1022   TopExp::MapShapesAndAncestors(mySbase, TopAbs_EDGE, TopAbs_FACE, mapedges);
1023   TopExp_Explorer ex;
1024   TopoDS_Edge FirstEdge;
1025   BRep_Builder BB;
1026
1027   TopoDS_Vertex Vprevious;
1028   gp_Pnt ptprev;
1029   Standard_Real dp;
1030
1031   while (!(LastOK && FirstOK)) {
1032     if (v1OK) {
1033       Vprevious=v2;
1034       ptprev=p2;
1035     }
1036     else {
1037       Vprevious=v1;
1038       ptprev=p1;
1039     }
1040     
1041     // find edge connected to v1 or v2:
1042     for (ex.Init(CurrentFace, TopAbs_EDGE); ex.More(); ex.Next()) {
1043       const TopoDS_Edge& rfe = TopoDS::Edge(ex.Current());
1044
1045       BRepExtrema_ExtPC projF(Vprevious, rfe);
1046
1047       if(projF.IsDone() && projF.NbExt() >=1) {
1048         Standard_Real dist2min = RealLast();
1049         Standard_Integer index = 0;
1050         for (Standard_Integer sol =1 ; sol <= projF.NbExt(); sol++) {
1051           if (projF.SquareDistance(sol) <= dist2min) {
1052             index = sol;
1053             dist2min = projF.SquareDistance(sol);
1054           }
1055         }
1056         if (index != 0) {
1057           if (dist2min <= BRep_Tool::Tolerance(rfe) * BRep_Tool::Tolerance(rfe)) {
1058             FirstEdge = rfe;
1059             // If the edge is not perpendicular to the plane of the rib
1060             // it is required to set Sliding(result) to false.
1061             if (result) {
1062               result=Standard_False;
1063               ve1 = TopExp::FirstVertex(rfe,Standard_True);
1064               ve2 = TopExp::LastVertex(rfe,Standard_True);
1065               BRepExtrema_ExtPF perp(ve1, fac);
1066               if (perp.IsDone()) {
1067                 gp_Pnt pe1=perp.Point(1);
1068                 perp.Perform(ve2, fac);
1069                 if (perp.IsDone()) {
1070                   gp_Pnt pe2=perp.Point(1);
1071                   if (pe1.Distance(pe2)<=BRep_Tool::Tolerance(rfe)) 
1072                     result=Standard_True;
1073                 }
1074               }
1075             }
1076             break;
1077           }
1078         }
1079       }
1080     }
1081     
1082     const TopTools_ListOfShape& L = mapedges.FindFromKey(FirstEdge);
1083     TopTools_ListIteratorOfListOfShape It(L);
1084
1085     for (; It.More(); It.Next()) {
1086       const TopoDS_Face& FF = TopoDS::Face(It.Value());
1087       if (!FF.IsSame(CurrentFace)) {
1088         CurrentFace = FF;
1089         break;
1090       }
1091     }
1092
1093     //modified by NIZNHY-PKV Fri Mar 22 16:50:53 2002 f
1094     //BRepAlgo_Section sectf (fac, CurrentFace, Standard_False);
1095     BRepAlgoAPI_Section sectf (fac, CurrentFace, Standard_False);
1096     //modified by NIZNHY-PKV Fri Mar 22 16:51:03 2002 t
1097     sectf.Approximation(Standard_True);
1098     sectf.Build();
1099
1100     TopoDS_Edge edg1;
1101     for (Ex.Init(sectf.Shape(), TopAbs_EDGE); Ex.More(); Ex.Next()) {
1102       edg1 = TopoDS::Edge(Ex.Current());
1103       v1=TopExp::FirstVertex(edg1,Standard_True);
1104       v2=TopExp::LastVertex(edg1,Standard_True);
1105       t1 = BRep_Tool::Tolerance(v1);
1106       t2 = BRep_Tool::Tolerance(v2);
1107       p1 = BRep_Tool::Pnt(v1);
1108       p2 = BRep_Tool::Pnt(v2);
1109       v1OK = p1.Distance(ptprev)<=t1;
1110       v2OK = p2.Distance(ptprev)<=t2;
1111       if (v1OK || v2OK) break;
1112     }    
1113     
1114     if (v1OK) {
1115       if (!FirstOK) {
1116         dp = p2.Distance(Firstpoint);
1117         if(dp <= 2*t2) {
1118           FirstOK = Standard_True;
1119           BB.UpdateVertex(v2, dp);
1120         }
1121       }
1122       if (!LastOK) {
1123         dp = p2.Distance(Lastpoint);
1124         if(dp <= 2*t2) {
1125           LastOK = Standard_True;
1126           BB.UpdateVertex(v2, dp);
1127         }
1128       }
1129     }
1130     else if (v2OK) {
1131       if (!FirstOK) {
1132         dp = p1.Distance(Firstpoint);
1133         if(dp <= 2*t1) {
1134           FirstOK = Standard_True;
1135           BB.UpdateVertex(v1, dp);
1136         }
1137       }
1138       if (!LastOK) {
1139         dp = p1.Distance(Lastpoint);
1140         if(dp <= 2*t1) {
1141           LastOK = Standard_True;
1142           BB.UpdateVertex(v1, dp);
1143         }
1144       }
1145     }
1146     else {
1147       // end by chaining the section
1148       return Standard_False;
1149     }
1150     TopTools_ListOfShape thelist1;
1151     mySlface.Bind(CurrentFace, thelist1);
1152     mySlface(CurrentFace).Append(edg1);
1153     myListOfEdges.Append(edg1);
1154   }
1155
1156   return result;
1157   
1158 }
1159
1160 //=======================================================================
1161 //function : MajMap
1162 //purpose  : management of descendants
1163 //=======================================================================
1164
1165 static void MajMap(const TopoDS_Shape& theB,
1166                    const LocOpe_LinearForm& theP,
1167                    TopTools_DataMapOfShapeListOfShape& theMap, // myMap
1168                    TopoDS_Shape& theFShape,  // myFShape
1169                    TopoDS_Shape& theLShape) // myLShape
1170 {
1171   TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
1172   if (exp.More()) {
1173     theFShape = exp.Current();
1174     TopTools_ListOfShape thelist;
1175     theMap.Bind(theFShape, thelist);
1176     for (exp.Init(theP.FirstShape(),TopAbs_FACE);exp.More();exp.Next()) {
1177       theMap(theFShape).Append(exp.Current());
1178     }
1179   }
1180   
1181   exp.Init(theP.LastShape(),TopAbs_WIRE);
1182   if (exp.More()) {
1183     theLShape = exp.Current();
1184     TopTools_ListOfShape thelist1;
1185     theMap.Bind(theLShape, thelist1);
1186     for (exp.Init(theP.LastShape(),TopAbs_FACE);exp.More();exp.Next()) {
1187       theMap(theLShape).Append(exp.Current());
1188     }
1189   }
1190   
1191   for (exp.Init(theB,TopAbs_EDGE); exp.More(); exp.Next()) {
1192     if (!theMap.IsBound(exp.Current())) {
1193       TopTools_ListOfShape thelist2; 
1194       theMap.Bind(exp.Current(), thelist2);
1195       theMap(exp.Current()) = theP.Shapes(exp.Current());
1196     }
1197   }
1198 }
1199
1200 //=======================================================================
1201 //function : SetGluedFaces
1202 //purpose  : management of faces of gluing
1203 //=======================================================================
1204
1205 static void SetGluedFaces(const TopTools_DataMapOfShapeListOfShape& theSlmap,
1206                           LocOpe_LinearForm& thePrism,
1207                           TopTools_DataMapOfShapeShape& theMap)
1208 {
1209   // Slidings
1210   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(theSlmap);
1211   if(!theSlmap.IsEmpty()) {
1212     for (; itm.More(); itm.Next()) {
1213       const TopoDS_Face& fac = TopoDS::Face(itm.Key());
1214       const TopTools_ListOfShape& ledg = itm.Value();
1215       TopTools_ListIteratorOfListOfShape it;
1216       for (it.Initialize(ledg); it.More(); it.Next()) {
1217         const TopTools_ListOfShape& gfac = thePrism.Shapes(it.Value());
1218         if (gfac.Extent() != 1) {
1219 #ifdef DEB
1220           cout << "Pb SetGluedFace" << endl;
1221 #endif
1222         }
1223         theMap.Bind(gfac.First(),fac);
1224       }
1225     }
1226   }
1227 }
1228