539a279b55ebbc84dbf5396a6d9f60acb0dbdbf0
[occt.git] / src / BRepFeat / BRepFeat.cxx
1 // Created on: 1996-04-23
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22
23 #include <BRepFeat.ixx>
24
25 //#include <BRepAlgo_Cut.hxx>
26
27 #include <BRepBuilderAPI.hxx>
28 #include <BRepAdaptor_Curve.hxx>
29 #include <TopExp_Explorer.hxx>
30 #include <TopTools_MapOfShape.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRep_Builder.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_TrimmedCurve.hxx>
35 #include <Geom2d_TrimmedCurve.hxx>
36 #include <Extrema_ExtPC.hxx>
37 #include <GeomAdaptor_Curve.hxx>
38 #include <BRepLProp.hxx>
39 #include <TopoDS.hxx>
40 #include <TopoDS_Vertex.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Shell.hxx>
44 #include <TopoDS_Solid.hxx>
45 #include <Precision.hxx>
46 #include <GCPnts_QuasiUniformDeflection.hxx>
47 #include <BRepTopAdaptor_FClass2d.hxx>
48 #include <Geom2dAdaptor_Curve.hxx>
49 #include <GeomProjLib.hxx>
50 #include <gp_Vec2d.hxx>
51 #include <BRepTools.hxx>
52 #include <Geom_Surface.hxx>
53 #include <Bnd_Box.hxx>
54 #include <BRepBndLib.hxx>
55 #include <BRepLib_MakeFace.hxx>
56 #include <Geom_RectangularTrimmedSurface.hxx>
57 #include <Geom_Plane.hxx>
58 #include <Geom_CylindricalSurface.hxx>
59 #include <Geom_ConicalSurface.hxx>
60 #include <LocOpe_CSIntersector.hxx>
61 #include <LocOpe_PntFace.hxx>
62 #include <LocOpe_BuildShape.hxx> 
63
64 #include <TColGeom_SequenceOfCurve.hxx>
65
66
67 #include <LocOpe.hxx>
68
69 #define NECHANTBARYC 11
70
71 //=======================================================================
72 //function : SampleEdges
73 //purpose  : 
74 //=======================================================================
75
76 void BRepFeat::SampleEdges(const TopoDS_Shape& theShape,
77                            TColgp_SequenceOfPnt& theSeq)
78 {
79   LocOpe::SampleEdges(theShape,theSeq);
80 }
81
82
83
84 //=======================================================================
85 //function : Barycenter
86 //purpose  : Calcul du barycentre des edges d'un shape
87 //=======================================================================
88
89 void BRepFeat::Barycenter(const TopoDS_Shape& S, 
90                           gp_Pnt& B)
91 {
92   TopTools_MapOfShape theMap;
93   TopExp_Explorer exp(S,TopAbs_EDGE);
94   TopLoc_Location Loc;
95   Handle(Geom_Curve) C;
96   Standard_Real f,l,prm;
97   gp_XYZ Bar(0.,0.,0.);
98   Standard_Integer i, nbp= 0;
99
100   for (; exp.More(); exp.Next()) {
101     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
102     if (!theMap.Add(edg)) {
103       continue;
104     }
105     if (!BRep_Tool::Degenerated(edg)) {
106       C = BRep_Tool::Curve(edg,Loc,f,l);
107       C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
108       for (i=1;i<NECHANTBARYC; i++) {
109         prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC;
110         Bar += C->Value(prm).XYZ();
111         nbp++;
112       }
113     }
114   }
115   // Adds every vertex
116   for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
117     if (theMap.Add(exp.Current())) {
118       Bar += (BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()))).XYZ();
119       nbp++;
120     }
121   }
122
123   Bar.Divide((Standard_Real)nbp);
124   B.SetXYZ(Bar);
125 }
126
127
128 //=======================================================================
129 //function : ParametricBarycenter
130 //purpose  : Calcul du barycentre "parametrique" shape sur une courbe
131 //=======================================================================
132
133 Standard_Real BRepFeat::ParametricBarycenter(const TopoDS_Shape& S, 
134                                              const Handle(Geom_Curve)& CC)
135 {
136   TopTools_MapOfShape theMap;
137   TopExp_Explorer exp(S,TopAbs_EDGE);
138   TopLoc_Location Loc;
139   Handle(Geom_Curve) C;
140   Standard_Real f,l,prm;
141   Standard_Integer i, nbp= 0;
142   GeomAdaptor_Curve TheCurve(CC);
143   Extrema_ExtPC extpc;
144   extpc.Initialize(TheCurve,CC->FirstParameter(),CC->LastParameter());
145   Standard_Real parbar = 0;
146
147   for (; exp.More(); exp.Next()) {
148     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
149     if (!theMap.Add(edg)) {
150       continue;
151     }
152     if (!BRep_Tool::Degenerated(edg)) {
153       C = BRep_Tool::Curve(edg,Loc,f,l);
154       C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
155       for (i=1;i<NECHANTBARYC; i++) {
156         prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC;
157         gp_Pnt pone = C->Value(prm);
158         // On projette sur CC
159         extpc.Perform(pone);
160         if (extpc.IsDone() && extpc.NbExt() >= 1) {
161           Standard_Real Dist2Min = extpc.SquareDistance(1);
162           Standard_Integer kmin = 1;
163           for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
164             Standard_Real Dist2 = extpc.SquareDistance(k);
165             if (Dist2 < Dist2Min) {
166               Dist2Min = Dist2;
167               kmin = k;
168             }
169           }
170           nbp++;
171           Standard_Real prmp = extpc.Point(kmin).Parameter();
172           parbar += prmp;
173         }         
174       }
175     }
176   }
177   // Adds every vertex
178   for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
179     if (theMap.Add(exp.Current())) {
180       gp_Pnt pone = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
181       // On projette sur CC
182       extpc.Perform(pone);
183       if (extpc.IsDone() && extpc.NbExt() >= 1) {
184             Standard_Real Dist2Min = extpc.SquareDistance(1);
185             Standard_Integer kmin = 1;
186             for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
187               Standard_Real Dist2 = extpc.SquareDistance(k);
188               if (Dist2 < Dist2Min) {
189                 Dist2Min = Dist2;
190                 kmin = k;
191               }
192             }
193             nbp++;
194       }   
195     }
196   }
197
198   parbar /=((Standard_Real)nbp);
199   return parbar;
200 }
201
202
203 //=======================================================================
204 //function : ParametricBarycenter
205 //purpose  : Calcul du barycentre "parametrique" shape sur une courbe
206 //=======================================================================
207
208 void BRepFeat::ParametricMinMax(const TopoDS_Shape& S, 
209                                 const Handle(Geom_Curve)& CC,
210                                 Standard_Real& prmin,
211                                 Standard_Real& prmax,
212                                 Standard_Real& prbmin,
213                                 Standard_Real& prbmax,
214                                 Standard_Boolean& flag,
215                                 const Standard_Boolean Ori)
216 {
217   LocOpe_CSIntersector ASI(S);
218   TColGeom_SequenceOfCurve scur;
219   scur.Append(CC);
220   ASI.Perform(scur);
221   if(ASI.IsDone() && ASI.NbPoints(1) >=1) {
222     if (!Ori) {
223       prmin = Min(ASI.Point(1,1).Parameter(), 
224                   ASI.Point(1, ASI.NbPoints(1)).Parameter());
225       prmax = Max(ASI.Point(1,1).Parameter(), 
226                   ASI.Point(1, ASI.NbPoints(1)).Parameter());
227     }
228     else {
229       TopAbs_Orientation Ori = ASI.Point(1,1).Orientation();
230       if (Ori ==  TopAbs_FORWARD) {
231         prmin = ASI.Point(1,1).Parameter();
232         prmax = ASI.Point(1, ASI.NbPoints(1)).Parameter();
233       }
234       else {
235         prmax = ASI.Point(1,1).Parameter();
236         prmin = ASI.Point(1, ASI.NbPoints(1)).Parameter();
237       }
238     }
239     flag = Standard_True;
240   }
241   else {
242     prmax = RealFirst();
243     prmin = RealLast();
244     flag = Standard_False; 
245   }
246
247   TopTools_MapOfShape theMap;
248   TopExp_Explorer exp(S,TopAbs_EDGE);
249   TopLoc_Location Loc;
250   Handle(Geom_Curve) C;
251   Standard_Real f,l,prm;
252 //  Standard_Integer i, nbp= 0;
253   Standard_Integer i;
254   GeomAdaptor_Curve TheCurve(CC);
255   Extrema_ExtPC extpc;
256   extpc.Initialize(TheCurve,CC->FirstParameter(),CC->LastParameter());
257   prbmin = RealLast();
258   prbmax = RealFirst();
259   for (; exp.More(); exp.Next()) {
260     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
261     if (!theMap.Add(edg)) {
262       continue;
263     }
264     if (!BRep_Tool::Degenerated(edg)) {
265       C = BRep_Tool::Curve(edg,Loc,f,l);
266       C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
267       for (i=1;i<NECHANTBARYC; i++) {
268         prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC;
269         gp_Pnt pone = C->Value(prm);
270         // On projette sur CC
271         extpc.Perform(pone);
272         if (extpc.IsDone() && extpc.NbExt() >= 1) {
273           Standard_Real Dist2Min = extpc.SquareDistance(1);
274           Standard_Integer kmin = 1;
275           for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
276             Standard_Real Dist2 = extpc.SquareDistance(k);
277             if (Dist2 < Dist2Min) {
278               Dist2Min = Dist2;
279               kmin = k;
280             }
281           }
282           Standard_Real prmp = extpc.Point(kmin).Parameter();
283           if (prmp <= prbmin) {
284             prbmin = prmp;
285           }
286           if (prmp >= prbmax) {
287             prbmax = prmp;
288           }
289         }         
290       }
291     }
292   }
293   // Adds every vertex
294   for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
295     if (theMap.Add(exp.Current())) {
296       gp_Pnt pone = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
297       // On projette sur CC
298       extpc.Perform(pone);
299       if (extpc.IsDone() && extpc.NbExt() >= 1) {
300         Standard_Real Dist2Min = extpc.SquareDistance(1);
301         Standard_Integer kmin = 1;
302         for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
303           Standard_Real Dist2 = extpc.SquareDistance(k);
304           if (Dist2 < Dist2Min) {
305             Dist2Min = Dist2;
306             kmin = k;
307           }
308         }
309         Standard_Real prmp = extpc.Point(kmin).Parameter();
310         if (prmp <= prbmin) {
311           prbmin = prmp;
312         }
313         if (prmp >= prbmax) {
314           prbmax = prmp;
315         }
316       }   
317     }
318   }
319 }
320
321
322
323
324 //=======================================================================
325 //function : IsIn
326 //purpose  : 
327 //=======================================================================
328
329 static Standard_Boolean IsIn (BRepTopAdaptor_FClass2d& FC,
330                                  Geom2dAdaptor_Curve      AC)
331 {
332  Standard_Real Def = 100*Precision::Confusion();
333  GCPnts_QuasiUniformDeflection QU(AC,Def);
334
335  for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
336    gp_Pnt2d P = AC.Value(QU.Parameter(i));
337    if (FC.Perform(P, Standard_False) == TopAbs_OUT) {
338      return Standard_False;
339      break;
340    } 
341  }
342  return Standard_True;
343 }
344
345
346 //=======================================================================
347 //function : PutInBoundsU
348 //purpose  : Recadre la courbe 2d dans les bounds de la face
349 //=======================================================================
350   //---------------
351   // Recadre en U.
352   //---------------
353
354 static void PutInBoundsU (Standard_Real      umin,
355                          Standard_Real      umax,
356                          Standard_Real      eps,
357                          Standard_Real      period,
358                          Standard_Real      f,
359                          Standard_Real      l,
360                          Handle(Geom2d_Curve)&       C2d)
361 {
362   gp_Pnt2d      Pf      = C2d->Value(f);
363   gp_Pnt2d      Pl      = C2d->Value(l);
364   gp_Pnt2d      Pm      = C2d->Value(0.34*f + 0.66*l);
365   Standard_Real minC    = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
366   Standard_Real maxC    = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
367   Standard_Real du = 0.;
368   if (minC< umin - eps) {
369     du = (int((umin - minC)/period) + 1)*period;
370   }
371   if (minC > umax + eps) {
372     du = -(int((minC - umax)/period) + 1)*period;
373   }
374   if (du != 0) {
375     gp_Vec2d T1(du,0.);
376     C2d->Translate(T1);
377     minC += du; maxC += du;
378   }
379     // Ajuste au mieux la courbe dans le domaine.
380   if (maxC > umax +100*eps) {
381     Standard_Real d1 = maxC - umax;
382     Standard_Real d2 = umin - minC + period;
383     if (d2 < d1) du =-period;
384     if ( du != 0.) {
385       gp_Vec2d T2(du,0.);
386       C2d->Translate(T2);
387     }
388   }
389
390
391
392 //=======================================================================
393 //function : PutInBoundsU
394 //purpose  : Recadre la courbe 2d dans les bounds de la face
395 //=======================================================================
396   //---------------
397   // Recadre en V.
398   //---------------
399
400 static void PutInBoundsV (Standard_Real     vmin,
401                          Standard_Real      vmax,
402                          Standard_Real      eps,
403                          Standard_Real      period,
404                          Standard_Real      f,
405                          Standard_Real      l,
406                          Handle(Geom2d_Curve)&       C2d)
407 {
408   gp_Pnt2d      Pf      = C2d->Value(f);
409   gp_Pnt2d      Pl      = C2d->Value(l);
410   gp_Pnt2d      Pm      = C2d->Value(0.34*f + 0.66*l);
411   Standard_Real minC    = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
412   Standard_Real maxC    = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
413   Standard_Real dv = 0.;
414   if (minC< vmin - eps) {
415     dv = (int((vmin - minC)/period) + 1)*period;
416   }
417   if (minC > vmax + eps) {
418     dv = -(int((minC - vmax)/period) + 1)*period;
419   }
420   if (dv != 0) {
421     gp_Vec2d T1(0.,dv);
422     C2d->Translate(T1);
423     minC += dv; maxC += dv;
424   }
425   // Ajuste au mieux la courbe dans le domaine.
426   if (maxC > vmax +100*eps) {
427     Standard_Real d1 = maxC - vmax;
428     Standard_Real d2 = vmin - minC + period;
429     if (d2 < d1) dv =-period;
430     if ( dv != 0.) {
431       gp_Vec2d T2(0.,dv);
432       C2d->Translate(T2);
433     }
434   }
435 }
436
437
438 //=======================================================================
439 //function : IsInside
440 //purpose  : 
441 //=======================================================================
442
443
444 Standard_Boolean BRepFeat::IsInside(const TopoDS_Face& F1,
445                                   const TopoDS_Face& F2)
446 {
447   TopExp_Explorer exp;
448   exp.Init(F1, TopAbs_EDGE);
449
450   Standard_Real   umin,umax,vmin,vmax, uperiod=0, vperiod=0;
451   Standard_Integer flagu = 0, flagv = 0; 
452   TopLoc_Location L; // Recup S avec la location pour eviter la copie.
453   Handle (Geom_Surface) S   = BRep_Tool::Surface(F2);
454 //  Standard_Real periodu, periodv; 
455   BRepTools::UVBounds(F2,umin,umax,vmin,vmax);
456
457   if (S->IsUPeriodic()) {
458     flagu = 1;
459     uperiod = S->UPeriod();
460   }
461
462   if (S->IsVPeriodic()) {
463     flagv = 1;
464     vperiod = S->VPeriod();
465   }
466   TopoDS_Shape aLocalShape = F2.Oriented(TopAbs_FORWARD);
467   BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalShape),Precision::Confusion());
468 //  BRepTopAdaptor_FClass2d FC (TopoDS::Face(F2.Oriented(TopAbs_FORWARD)),
469 //                              Precision::Confusion());
470   for(; exp.More(); exp.Next()) {
471     Standard_Real   f1,l1;
472     Handle(Geom_Curve) C0 = BRep_Tool::Curve(TopoDS::Edge(exp.Current()),f1,l1);
473     Handle(Geom2d_Curve) C = GeomProjLib::Curve2d(C0,f1,l1,S);        
474     TopoDS_Edge E = TopoDS::Edge(exp.Current());
475     if(flagu == 1 || flagv == 1) {
476       Standard_Real   eps = BRep_Tool::Tolerance(E);
477       BRep_Tool::Range(E,f1,l1);  
478       if(flagu == 1) PutInBoundsU(umin, umax, eps, uperiod, f1, l1, C); 
479       if(flagv == 1) PutInBoundsV(vmin, vmax, eps, vperiod, f1, l1, C); 
480     }
481     Geom2dAdaptor_Curve  AC(C,f1,l1);
482     if (!IsIn(FC,AC)) {
483       return Standard_False;
484       break;
485     }
486   }
487   return Standard_True;
488 }
489
490
491
492 //=======================================================================
493 //function : FaceUntil
494 //purpose  : 
495 //=======================================================================
496
497
498 void BRepFeat::FaceUntil(const TopoDS_Shape& Sbase,
499                          TopoDS_Face& FUntil)
500 {
501   Bnd_Box B;
502   BRepBndLib::Add(Sbase,B);
503   Standard_Real c[6], bnd;
504   B.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
505   bnd = c[0];
506   for(Standard_Integer i = 1 ; i < 6; i++) {
507     if(c[i] > bnd) bnd = c[i];
508   }
509   bnd = 10*bnd;
510
511   
512   Handle(Geom_Surface) s = BRep_Tool::Surface(FUntil);
513   Handle(Standard_Type) styp = s->DynamicType();
514   if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
515     s = Handle(Geom_RectangularTrimmedSurface)::DownCast(s)->BasisSurface();
516     styp = s->DynamicType();
517   }
518   Handle(Geom_RectangularTrimmedSurface) str;
519   if (styp == STANDARD_TYPE(Geom_Plane)) {
520     str = new Geom_RectangularTrimmedSurface
521       (s, bnd, -bnd, bnd, -bnd, Standard_True, Standard_True);
522   }
523   else if (styp == STANDARD_TYPE(Geom_CylindricalSurface)) {
524     str = new Geom_RectangularTrimmedSurface
525       (s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True);
526   }
527   else if (styp == STANDARD_TYPE(Geom_ConicalSurface)) {
528     str = new Geom_RectangularTrimmedSurface
529       (s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True);
530   }
531   else {
532     FUntil.Nullify();
533     return;
534   }
535
536   FUntil = BRepLib_MakeFace(str, Precision::Confusion());
537 }
538
539
540
541 //=======================================================================
542 //function : Tool
543 //purpose  : 
544 //=======================================================================
545
546 TopoDS_Solid BRepFeat::Tool(const TopoDS_Shape& SRef,
547                             const TopoDS_Face& Fac,
548                             const TopAbs_Orientation Orf)
549 {
550   TopTools_ListOfShape lfaces;
551 //  for (TopExp_Explorer exp(SRef,TopAbs_FACE); exp.More(); exp.Next()) {
552   TopExp_Explorer exp(SRef,TopAbs_FACE) ;
553   for ( ; exp.More(); exp.Next()) {
554     if (exp.Current().ShapeType() == TopAbs_FACE) {
555       lfaces.Append(exp.Current());
556     }
557   }
558    
559   LocOpe_BuildShape bs(lfaces);
560   const TopoDS_Shape& Res = bs.Shape();
561   TopoDS_Shell Sh;
562   if (Res.ShapeType() == TopAbs_SHELL) {
563     // faire un solide
564     Sh = TopoDS::Shell(Res);
565   }
566   else if (Res.ShapeType() == TopAbs_SOLID) {
567     exp.Init(Res,TopAbs_SHELL);
568     Sh = TopoDS::Shell(exp.Current());
569     exp.Next();
570     if (exp.More()) {
571       Sh.Nullify();
572     }
573   }
574
575   if (Sh.IsNull()) {
576     TopoDS_Solid So;
577     return So;
578   }
579
580
581   Sh.Orientation(TopAbs_FORWARD);
582
583   TopAbs_Orientation orient = TopAbs_FORWARD;
584
585   for (exp.Init(Sh,TopAbs_FACE); exp.More(); exp.Next()) {
586     if (exp.Current().IsSame(Fac)) {
587       orient = exp.Current().Orientation();
588       break;
589     }
590   }
591   
592   Standard_Boolean reverse = Standard_False;
593   if ((orient == Fac.Orientation() && Orf == TopAbs_REVERSED) ||
594       (orient != Fac.Orientation() && Orf == TopAbs_FORWARD)) {
595     reverse = Standard_True;
596   }
597
598   if (reverse) {
599     Sh.Reverse();
600   }
601
602   BRep_Builder B;
603   TopoDS_Solid Soc;
604   B.MakeSolid(Soc);
605   B.Add(Soc,Sh);
606   return Soc;
607 }
608
609
610 //=======================================================================
611 //function : Print
612 //purpose  : Print the error Description of a StatusError on a stream.
613 //=======================================================================
614         
615 Standard_OStream& BRepFeat::Print(const BRepFeat_StatusError se, 
616                                   Standard_OStream& s)
617 {
618   switch(se) {
619   case BRepFeat_OK :
620     s << "No error";
621     break;
622   case BRepFeat_BadDirect :
623     s << "Directions must be opposite";
624     break;
625   case BRepFeat_BadIntersect :
626     s << "Intersection failure";
627     break;
628   case BRepFeat_EmptyBaryCurve :
629     s << "Empty BaryCurve";
630     break;
631   case BRepFeat_EmptyCutResult :
632     s << "Failure in Cut : Empty resulting shape";
633     break;;
634   case BRepFeat_FalseSide :
635     s << "Verify plane and wire orientation";
636     break;
637   case BRepFeat_IncDirection : 
638     s << "Incoherent Direction for shapes From and Until";
639     break;
640   case BRepFeat_IncSlidFace : 
641     s << "Sliding face not in Base shape";
642     break;
643   case BRepFeat_IncParameter :
644     s << "Incoherent Parameter : shape Until before shape From";
645     break;
646   case BRepFeat_IncTypes : 
647     s << "Invalid option for faces From and Until : 1 Support and 1 not";
648     break;
649   case BRepFeat_IntervalOverlap :
650     s << "Shapes From and Until overlap";
651     break;
652   case BRepFeat_InvFirstShape :
653     s << "Invalid First shape : more than 1 face";
654     break;
655   case BRepFeat_InvOption :
656     s << "Invalid option";
657     break;
658   case BRepFeat_InvShape :
659     s << "Invalid shape";
660     break;
661   case BRepFeat_LocOpeNotDone :
662     s << "Local Operation not done";
663     break;
664   case BRepFeat_LocOpeInvNotDone :
665     s << "Local Operation : intersection line conflict";
666     break;
667   case BRepFeat_NoExtFace :
668     s << "No Extreme faces";
669     break;
670   case BRepFeat_NoFaceProf :
671     s << "No Face Profile";
672     break;
673   case BRepFeat_NoGluer :
674     s << "Gluer Failure";
675     break;
676   case BRepFeat_NoIntersectF :
677     s << "No intersection between Feature and shape From";
678     break;
679   case BRepFeat_NoIntersectU :
680     s << "No intersection between Feature and shape Until";
681     break;
682   case BRepFeat_NoParts :
683     s << "No parts of tool kept";
684     break;
685   case BRepFeat_NoProjPt :
686     s << "No projection points";
687     break;
688   case BRepFeat_NotInitialized :
689     s << "Fields not initialized";
690     break;
691   case BRepFeat_NotYetImplemented : 
692     s << "Not yet implemented";
693     break;
694   case BRepFeat_NullRealTool :
695     s << "Real Tool : Null DPrism";
696     break;
697   case BRepFeat_NullToolF :
698     s << "Null Tool : Invalid type for shape Form";
699     break;
700   case BRepFeat_NullToolU :
701     s << "Null Tool : Invalid type for shape Until";
702     break;
703   }
704   return s;
705 }
706