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