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