0023429: BRepFeat_SplitShape algorithm misses some section edges while building resul...
[occt.git] / src / LocOpe / LocOpe_DPrism.cxx
1 // Created on: 1996-09-04
2 // Created by: Olga PILLOT
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 #include <LocOpe_DPrism.ixx>
23
24
25 #include <BRep_Builder.hxx>
26 #include <BRep_Tool.hxx>
27 #include <Geom_RectangularTrimmedSurface.hxx>
28
29 #include <BRepLib_MakeVertex.hxx>
30 #include <BRepLib_MakeEdge.hxx>
31 #include <BRepLib_MakeWire.hxx>
32 #include <BRepLib_MakeFace.hxx>
33 #include <BRepClass3d_SolidClassifier.hxx>
34
35 #include <BRepLib.hxx>
36
37 #include <TopTools_MapOfShape.hxx>
38 #include <TopTools_ListOfShape.hxx>
39 #include <TopTools_ListIteratorOfListOfShape.hxx>
40 #include <TopTools_DataMapOfShapeListOfShape.hxx>
41 #include <TopTools.hxx>
42 #include <TopoDS_Compound.hxx>
43 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
44 #include <TopExp_Explorer.hxx>
45
46 #include <LocOpe_BuildShape.hxx>
47 #include <LocOpe.hxx>
48 #include <TColgp_SequenceOfPnt.hxx>
49
50 #include <gp_Ax3.hxx>
51 #include <gp_Pln.hxx>
52 #include <gp_Vec.hxx>
53 #include <gp_Lin.hxx>
54
55 #include <Geom_Surface.hxx>
56 #include <Geom_RectangularTrimmedSurface.hxx>
57 #include <Geom_TrimmedCurve.hxx>
58 #include <Geom_Plane.hxx>
59 #include <Geom_Line.hxx>
60 #include <Geom_Curve.hxx>
61
62 #include <TopoDS.hxx>
63 #include <TopExp.hxx>
64 #include <Precision.hxx>
65 #include <BSplCLib.hxx>
66 #include <gp.hxx>
67 #include <BRepTools.hxx>
68 #include <Standard_ConstructionError.hxx>
69
70 #ifdef DEB
71 Standard_IMPORT Standard_Boolean BRepFeat_GettraceFEAT();
72 #endif
73
74 #define NECHANT 7 // voir BRepFeat.cxx
75
76 //=======================================================================
77 //function : LocOpe_DPrism
78 //purpose  : 
79 //=======================================================================
80
81 LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face&  Spine,
82                              const Standard_Real Height1,
83                              const Standard_Real Height2,
84                              const Standard_Real Angle):
85   mySpine(Spine)
86 {
87   Standard_Integer i ;
88
89   myHeight = Height1 + Height2;
90   Standard_Real y =  Height1*sin(Angle);
91   Standard_Real z =  Height1*cos(Angle);
92
93   TopoDS_Vertex Vert2  = BRepLib_MakeVertex(gp_Pnt(0,y,z));
94
95   Standard_Real y1 =  -Height2*sin(Angle);
96   Standard_Real z1 =  -Height2*cos(Angle);
97
98   TopoDS_Vertex Vert1  = BRepLib_MakeVertex(gp_Pnt(0,y1,z1));  
99
100   myProfile2 = BRepLib_MakeEdge(Vert1, Vert2);
101   
102   Standard_Real Umin,Umax,Vmin,Vmax;
103   Umax = 0.;
104   Umin = 0.;
105   Vmin = 0.;
106   Vmax = 0.;
107
108   BRepTools::UVBounds(Spine,Umin,Umax,Vmin,Vmax);
109   Standard_Real Deltay = Max(Umax-Umin,Vmax-Vmin) + Abs(y);
110   Deltay*=2;
111   
112   TopoDS_Vertex Vert3  = BRepLib_MakeVertex(gp_Pnt(0, y + Deltay, z));
113   myProfile3 = BRepLib_MakeEdge(Vert2, Vert3);
114
115   Umax = 0.;
116   Umin = 0.;
117   Vmin = 0.;
118   Vmax = 0.;
119
120   BRepTools::UVBounds(Spine,Umin,Umax,Vmin,Vmax);
121   Standard_Real Deltay1 = Max(Umax-Umin,Vmax-Vmin) + Abs(y1);
122   Deltay1*=2;
123
124   TopoDS_Vertex Vert4  = BRepLib_MakeVertex(gp_Pnt(0, y1+Deltay1, z1));
125   myProfile1 = BRepLib_MakeEdge(Vert4, Vert1);
126
127   myProfile  = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3);
128
129   myDPrism.Perform(mySpine,myProfile,gp::XOY()); 
130
131
132   if (myDPrism.IsDone()) {
133     LocOpe_BuildShape BS;
134     BRep_Builder B;
135     TopoDS_Compound C;
136     TopoDS_Compound D;
137     TopTools_ListOfShape lfaces,lcomplete;
138     
139     
140     B.MakeCompound(C);
141     TopTools_ListIteratorOfListOfShape it;
142     TopExp_Explorer ExpS(mySpine,TopAbs_EDGE);
143     TopTools_MapOfShape View;
144     for (; ExpS.More(); ExpS.Next()) {
145       const TopoDS_Shape& ES = ExpS.Current();
146       const TopTools_ListOfShape& lffs = 
147         myDPrism.GeneratedShapes(ES, myProfile1);
148       for (it.Initialize(lffs); it.More(); it.Next()) {
149         if (View.Add(it.Value()))
150           B.Add(C,it.Value());
151       }
152     }
153     
154     TopTools_IndexedDataMapOfShapeListOfShape theMapEF;
155     TopExp::MapShapesAndAncestors(C,TopAbs_EDGE,TopAbs_FACE,theMapEF);
156     View.Clear();
157     
158     for ( i = 1; i<=theMapEF.Extent(); i++) {
159       if (theMapEF(i).Extent() == 1) {
160         const TopoDS_Edge& edg = TopoDS::Edge(theMapEF.FindKey(i));
161         const TopoDS_Face& fac = TopoDS::Face(theMapEF(i).First());
162         if (View.Add(fac)) {
163           TopoDS_Shape aLocalShape = fac.EmptyCopied();
164           TopoDS_Face newFace(TopoDS::Face(aLocalShape));
165 //        TopoDS_Face newFace(TopoDS::Face(fac.EmptyCopied()));
166           TopExp_Explorer exp;
167           for (exp.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
168                exp.More(); exp.Next()) {
169 //          for (TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE); 
170             TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE) ;
171             for ( ; exp2.More(); exp2.Next()) {
172               if (exp2.Current().IsSame(edg)) {
173                 B.Add(newFace,exp.Current());
174                 lfaces.Append(newFace);
175                 lcomplete.Append(newFace);
176                 break;
177               }
178             }
179             if (exp2.More()) {
180               break;
181             }
182           }
183         }
184       }
185     }
186     
187     BS.Perform(lfaces);
188     myFirstShape = BS.Shape();
189
190
191     B.MakeCompound(D);
192     
193     ExpS.ReInit();
194     View.Clear();
195     
196     for (; ExpS.More(); ExpS.Next()) {
197       const TopoDS_Shape& ES = ExpS.Current();
198       const TopTools_ListOfShape& lfls = 
199         myDPrism.GeneratedShapes(ES, myProfile3);
200       for (it.Initialize(lfls); it.More(); it.Next()) {
201         if (View.Add(it.Value()))
202           B.Add(D,it.Value());
203       }
204     }
205     
206     lfaces.Clear();
207     theMapEF.Clear();
208     TopExp::MapShapesAndAncestors(D,TopAbs_EDGE,TopAbs_FACE,theMapEF);
209     View.Clear();
210     
211     for (i = 1; i<=theMapEF.Extent(); i++) {
212       if (theMapEF(i).Extent() == 1) {
213         const TopoDS_Edge& edg = TopoDS::Edge(theMapEF.FindKey(i));
214         const TopoDS_Face& fac = TopoDS::Face(theMapEF(i).First());
215         if (View.Add(fac)) {
216           TopoDS_Shape aLocalShape = fac.EmptyCopied();
217           TopoDS_Face newFace(TopoDS::Face(aLocalShape));
218 //        TopoDS_Face newFace(TopoDS::Face(fac.EmptyCopied()));
219           TopExp_Explorer exp;
220           for (exp.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
221                exp.More(); exp.Next()) {
222 //          for (TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE); 
223             TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE) ;
224             for ( ; exp2.More(); exp2.Next()) {
225               if (exp2.Current().IsSame(edg)) {
226                 B.Add(newFace,exp.Current());
227                 lfaces.Append(newFace);
228                 lcomplete.Append(newFace);
229                 break;
230               }
231             }
232             if (exp2.More()) {
233               break;
234             }
235           }
236         }
237       }
238     }
239     BS.Perform(lfaces);
240     myLastShape = BS.Shape();
241
242
243     View.Clear();
244
245     for (ExpS.ReInit(); ExpS.More(); ExpS.Next()) {
246       const TopoDS_Shape& ES = ExpS.Current();
247       const TopTools_ListOfShape& lffs =
248         myDPrism.GeneratedShapes(ES, myProfile2);
249
250       for (it.Initialize(lffs); it.More(); it.Next()) {
251         if (it.Value().ShapeType() == TopAbs_EDGE) {
252           break;
253         }
254       }
255       if (it.More()) {
256         TopoDS_Shape RemovedEdge = it.Value();
257         TopoDS_Face NewFace;
258         TopoDS_Wire NewWire;
259         B.MakeWire(NewWire);
260         TopAbs_Orientation Orref = TopAbs_FORWARD;
261         TopExp_Explorer exp;
262         for (it.Initialize(lffs); it.More(); it.Next()) {
263           if (it.Value().ShapeType() == TopAbs_FACE) {
264             exp.Init(it.Value().Oriented(TopAbs_FORWARD),TopAbs_WIRE);
265             const TopoDS_Shape theWire = exp.Current();
266             if (NewFace.IsNull()) {
267               Handle(Geom_Surface) S = 
268                 BRep_Tool::Surface(TopoDS::Face(it.Value()));
269               if (S->DynamicType() == 
270                   STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
271                 S = Handle(Geom_RectangularTrimmedSurface)::
272                   DownCast(S)->BasisSurface();
273               }
274               if (S->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
275                 break;
276               }
277
278               B.MakeFace(NewFace,S,BRep_Tool::
279                          Tolerance(TopoDS::Face(it.Value())));
280               NewFace.Orientation(TopAbs_FORWARD);
281               Orref = theWire.Orientation();
282               for (exp.Init(theWire.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
283                    exp.More(); exp.Next()) {
284                 if (!exp.Current().IsSame(RemovedEdge)) {
285                   B.Add(NewWire,exp.Current());
286                 }
287               }
288             }
289             else {
290               for (exp.Init(theWire.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
291                    exp.More(); exp.Next()) {
292                 if (!exp.Current().IsSame(RemovedEdge)) {
293                   if (theWire.Orientation() != Orref) { // Les 2 faces planes ont des normales opposees
294                     B.Add(NewWire,exp.Current());
295                   }
296                   else {
297                     B.Add(NewWire,exp.Current().Reversed());
298                   }
299                 }
300               }
301             }
302           }
303         }
304         if (!NewFace.IsNull()) {
305           B.Add(NewFace,NewWire.Oriented(Orref));
306           lcomplete.Append(NewFace);
307           TopTools_ListOfShape thelist;
308           myMap.Bind(ES, thelist);
309           myMap(ES).Append(NewFace);
310         }
311         else {
312           for (it.Initialize(lffs); it.More(); it.Next()) {
313             if (View.Add(it.Value()) && 
314                 it.Value().ShapeType() == TopAbs_FACE) {
315               lcomplete.Append(it.Value());
316               
317             }
318           }
319         }
320       }
321       else {
322         for (it.Initialize(lffs); it.More(); it.Next()) {
323           if (View.Add(it.Value()) && it.Value().ShapeType() 
324               == TopAbs_FACE) {
325             lcomplete.Append(it.Value());
326           }
327         }
328       }
329
330       TopExp_Explorer ExpS2;
331       for (ExpS2.Init(ES,TopAbs_VERTEX);ExpS2.More(); ExpS2.Next()) {
332         const TopTools_ListOfShape& ls2 = 
333           myDPrism.GeneratedShapes(ExpS2.Current(), myProfile2);
334         for (it.Initialize(ls2); it.More(); it.Next()) {
335           if (View.Add(it.Value()) && it.Value().ShapeType() 
336               == TopAbs_FACE) {
337             lcomplete.Append(it.Value());
338           }
339         }
340       }
341     }
342
343     BS.Perform(lcomplete);
344     myRes = BS.Shape();
345     BRepLib::UpdateTolerances(myRes);
346   }
347 }
348
349
350
351 //=======================================================================
352 //function : LocOpe_DPrism
353 //purpose  : 
354 //=======================================================================
355
356 LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face&   Spine,
357                              const Standard_Real Height,
358                              const Standard_Real Angle):
359    mySpine(Spine)
360 {
361   Standard_Integer i ;
362   myHeight = Height;
363   Standard_Real y =  Height*sin(Angle);
364   Standard_Real z =  Height*cos(Angle);
365
366   TopoDS_Vertex Vert1  = BRepLib_MakeVertex(gp_Pnt(0, 0, 0));
367   TopoDS_Vertex Vert2  = BRepLib_MakeVertex(gp_Pnt(0,y,z));
368   myProfile2 = BRepLib_MakeEdge(Vert1, Vert2);
369   
370   Standard_Real Umin,Umax,Vmin,Vmax;
371   BRepTools::UVBounds(Spine,Umin,Umax,Vmin,Vmax);
372   Standard_Real Deltay = Max(Umax-Umin,Vmax-Vmin) + Abs(y);
373   Deltay*=2;
374   
375   TopoDS_Vertex Vert3  = BRepLib_MakeVertex(gp_Pnt(0, y + Deltay,z));
376   myProfile3 = BRepLib_MakeEdge(Vert2, Vert3);
377   
378   TopoDS_Vertex Vert4  = BRepLib_MakeVertex(gp_Pnt(0, Deltay,0));
379   myProfile1 = BRepLib_MakeEdge(Vert4, Vert1);
380   
381   myProfile = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3);
382   myDPrism.Perform(mySpine,myProfile,gp::XOY()); 
383
384
385   if (myDPrism.IsDone()) {
386     LocOpe_BuildShape BS;
387     BRep_Builder B;
388     TopoDS_Compound C;
389     TopoDS_Compound D;
390     TopTools_ListOfShape lfaces,lcomplete;
391     
392     
393     B.MakeCompound(C);
394     TopTools_ListIteratorOfListOfShape it;
395     TopExp_Explorer ExpS(mySpine,TopAbs_EDGE);
396     TopTools_MapOfShape View;
397     for (; ExpS.More(); ExpS.Next()) {
398       const TopoDS_Shape& ES = ExpS.Current();
399       const TopTools_ListOfShape& lffs = 
400         myDPrism.GeneratedShapes(ES, myProfile1);
401       for (it.Initialize(lffs); it.More(); it.Next()) {
402         if (View.Add(it.Value()))
403           B.Add(C,it.Value());
404       }
405     }
406     
407     TopTools_IndexedDataMapOfShapeListOfShape theMapEF;
408     TopExp::MapShapesAndAncestors(C,TopAbs_EDGE,TopAbs_FACE,theMapEF);
409     View.Clear();
410     
411     for ( i = 1; i<=theMapEF.Extent(); i++) {
412       if (theMapEF(i).Extent() == 1) {
413         const TopoDS_Edge& edg = TopoDS::Edge(theMapEF.FindKey(i));
414         const TopoDS_Face& fac = TopoDS::Face(theMapEF(i).First());
415         if (View.Add(fac)) {
416           TopoDS_Shape aLocalShape = fac.EmptyCopied();
417           TopoDS_Face newFace(TopoDS::Face(aLocalShape));
418 //        TopoDS_Face newFace(TopoDS::Face(fac.EmptyCopied()));
419           TopExp_Explorer exp;
420           for (exp.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
421                exp.More(); exp.Next()) {
422 //          for (TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE); 
423             TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE) ;
424             for ( ; exp2.More(); exp2.Next()) {
425               if (exp2.Current().IsSame(edg)) {
426                 B.Add(newFace,exp.Current());
427                 lfaces.Append(newFace);
428                 lcomplete.Append(newFace);
429                 break;
430               }
431             }
432             if (exp2.More()) {
433               break;
434             }
435           }
436         }
437       }
438     }
439     
440     BS.Perform(lfaces);
441     myFirstShape = BS.Shape();
442
443
444     B.MakeCompound(D);
445     
446     ExpS.ReInit();
447     View.Clear();
448     
449     for (; ExpS.More(); ExpS.Next()) {
450       const TopoDS_Shape& ES = ExpS.Current();
451       const TopTools_ListOfShape& lfls = 
452         myDPrism.GeneratedShapes(ES, myProfile3);
453       for (it.Initialize(lfls); it.More(); it.Next()) {
454         if (View.Add(it.Value()))
455           B.Add(D,it.Value());
456       }
457     }
458     
459     lfaces.Clear();
460     theMapEF.Clear();
461     TopExp::MapShapesAndAncestors(D,TopAbs_EDGE,TopAbs_FACE,theMapEF);
462     View.Clear();
463     
464     for (i = 1; i<=theMapEF.Extent(); i++) {
465       if (theMapEF(i).Extent() == 1) {
466         const TopoDS_Edge& edg = TopoDS::Edge(theMapEF.FindKey(i));
467         const TopoDS_Face& fac = TopoDS::Face(theMapEF(i).First());
468         if (View.Add(fac)) {
469           TopoDS_Shape aLocalShape = fac.EmptyCopied();
470           TopoDS_Face newFace(TopoDS::Face(aLocalShape));
471 //        TopoDS_Face newFace(TopoDS::Face(fac.EmptyCopied()));
472           TopExp_Explorer exp;
473           for (exp.Init(fac.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
474                exp.More(); exp.Next()) {
475 //          for (TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE); 
476             TopExp_Explorer exp2(exp.Current(),TopAbs_EDGE) ;
477             for ( ; exp2.More(); exp2.Next()) {
478               if (exp2.Current().IsSame(edg)) {
479                 B.Add(newFace,exp.Current());
480                 lfaces.Append(newFace);
481                 lcomplete.Append(newFace);
482                 break;
483               }
484             }
485             if (exp2.More()) {
486               break;
487             }
488           }
489         }
490       }
491     }
492     BS.Perform(lfaces);
493     myLastShape = BS.Shape();
494
495
496     View.Clear();
497     for (ExpS.ReInit(); ExpS.More(); ExpS.Next()) {
498       const TopoDS_Shape& ES = ExpS.Current();
499       const TopTools_ListOfShape& ls = 
500         myDPrism.GeneratedShapes(ES, myProfile2);
501       for (it.Initialize(ls); it.More(); it.Next()) {
502         if (View.Add(it.Value())) {
503           lcomplete.Append(it.Value());
504         }
505       }
506       TopExp_Explorer ExpS2;
507       for (ExpS2.Init(ES,TopAbs_VERTEX);ExpS2.More(); ExpS2.Next()) {
508         const TopTools_ListOfShape& ls2 = 
509           myDPrism.GeneratedShapes(ExpS2.Current(), myProfile2);
510         for (it.Initialize(ls2); it.More(); it.Next()) {
511           if (View.Add(it.Value()) && it.Value().
512               ShapeType() == TopAbs_FACE) {
513             lcomplete.Append(it.Value());
514           }
515         }
516       }
517     }
518
519     BS.Perform(lcomplete);
520     myRes = BS.Shape();
521     BRepLib::UpdateTolerances(myRes);
522   }
523
524 }
525
526
527 //=======================================================================
528 //function : IsDone
529 //purpose  : 
530 //=======================================================================
531
532 Standard_Boolean LocOpe_DPrism::IsDone() const
533 {
534   return myDPrism.IsDone();
535 }
536
537
538 //=======================================================================
539 //function : Shape
540 //purpose  : 
541 //=======================================================================
542
543 const TopoDS_Shape& LocOpe_DPrism::Shape () const
544 {
545   if (!myDPrism.IsDone()) {
546     StdFail_NotDone::Raise();
547   }
548   return myRes;
549 }
550
551
552 //=======================================================================
553 //function : Spine
554 //purpose  : 
555 //=======================================================================
556
557 const TopoDS_Shape& LocOpe_DPrism::Spine () const
558 {
559   return mySpine;
560 }
561
562 //=======================================================================
563 //function : Profile
564 //purpose  : 
565 //=======================================================================
566
567 const TopoDS_Shape& LocOpe_DPrism::Profile () const
568 {
569   return myProfile;
570 }
571
572
573 //=======================================================================
574 //function : FirstShape
575 //purpose  : 
576 //=======================================================================
577
578 const TopoDS_Shape& LocOpe_DPrism::FirstShape () const
579 {
580   return myFirstShape;
581 }
582
583 //=======================================================================
584 //function : LastShape
585 //purpose  : 
586 //=======================================================================
587
588 const TopoDS_Shape& LocOpe_DPrism::LastShape () const
589 {
590   return myLastShape;
591 }
592
593
594 //=======================================================================
595 //function : Shapes
596 //purpose  : 
597 //=======================================================================
598
599 const TopTools_ListOfShape& 
600  LocOpe_DPrism::Shapes (const TopoDS_Shape& S)const
601 {
602   if (!myDPrism.IsDone()) {
603     StdFail_NotDone::Raise();
604   }
605   if (myMap.IsBound(S)) {
606     return myMap(S);
607   }
608   else {
609     return myDPrism.GeneratedShapes(S,myProfile2);
610   }
611 }
612
613
614 //=======================================================================
615 //function : Curves
616 //purpose  : 
617 //=======================================================================
618
619 void LocOpe_DPrism::Curves(TColGeom_SequenceOfCurve& Scurves) const
620 {
621   // Retrieves dy and dz with myProfile2
622   TopoDS_Vertex V1,V2;
623   TopExp::Vertices(myProfile2,V1,V2);
624   gp_Pnt P1 = BRep_Tool::Pnt(V1);
625   gp_Pnt P2 = BRep_Tool::Pnt(V2);
626   Standard_Real dy = P2.Y() - P1.Y(); 
627   Standard_Real dz = P2.Z() - P1.Z(); 
628   Scurves.Clear();
629   Handle(Geom_Surface) S = BRep_Tool::Surface(mySpine);
630   if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
631     S = Handle(Geom_RectangularTrimmedSurface)::
632       DownCast(S)->BasisSurface();
633   }
634
635   Handle(Geom_Plane) PP = Handle(Geom_Plane)::DownCast(S);
636   if (PP.IsNull()) {
637     Standard_ConstructionError::Raise();
638   }
639
640   gp_Pln P = PP->Pln();
641   gp_Dir Normale(P.Axis().Direction());
642   if (!P.Direct()) {
643     Normale.Reverse();
644   }
645
646   TopTools_MapOfShape theMap;
647   TopExp_Explorer exp(mySpine.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
648   TopLoc_Location Loc;
649   Handle(Geom_Curve) C;
650   Standard_Real f,l,prm;
651   Standard_Integer i;
652
653   for (; exp.More(); exp.Next()) {
654     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
655     if (!theMap.Add(edg)) {
656       continue;
657     }
658     if (!BRep_Tool::Degenerated(edg)) {
659       C = BRep_Tool::Curve(edg,Loc,f,l);
660       C = Handle(Geom_Curve)::
661         DownCast(C->Transformed(Loc.Transformation()));
662       Standard_Real u1 = -2*Abs(myHeight);
663       Standard_Real u2 = 2*Abs(myHeight);
664         
665       for (i=0; i<=NECHANT; i++) {
666         prm = ((NECHANT-i)*f+i*l)/NECHANT;
667         gp_Pnt pt;
668         gp_Vec d1;
669         C->D1(prm,pt,d1);
670         if (exp.Current().Orientation() == TopAbs_REVERSED) {
671           d1.Reverse();
672         }
673         d1.Normalize();
674         gp_Dir locy = Normale.Crossed(d1);
675         gp_Vec ldir = dy*locy.XYZ() + dz*Normale.XYZ();
676         gp_Lin lin(pt, ldir);
677         Handle(Geom_Line) Lin = new Geom_Line(lin);
678         Handle(Geom_TrimmedCurve) trlin = 
679           new Geom_TrimmedCurve(Lin, u1, u2, Standard_True);
680         Scurves.Append(trlin);
681       }
682     }
683   }
684 }
685
686
687 //=======================================================================
688 //function : BarycCurve
689 //purpose  : 
690 //=======================================================================
691
692 Handle(Geom_Curve) LocOpe_DPrism::BarycCurve() const
693 {
694   TopoDS_Vertex V1,V2;
695   TopExp::Vertices(myProfile2,V1,V2);
696   gp_Pnt P1 = BRep_Tool::Pnt(V1);
697   gp_Pnt P2 = BRep_Tool::Pnt(V2);
698   Standard_Real dz = P2.Z() - P1.Z(); 
699
700   Handle(Geom_Surface) S = BRep_Tool::Surface(mySpine);
701   if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
702     S = Handle(Geom_RectangularTrimmedSurface)::
703       DownCast(S)->BasisSurface();
704   }
705
706   Handle(Geom_Plane) PP = Handle(Geom_Plane)::DownCast(S);
707   if (PP.IsNull()) {
708     Standard_ConstructionError::Raise();
709   }
710
711   gp_Pln P = PP->Pln();
712   gp_Dir Normale(P.Axis().Direction());
713   if (!P.Direct()) {
714     Normale.Reverse();
715   }
716   if (mySpine.Orientation() == TopAbs_REVERSED) {
717 #ifdef DEB
718     Standard_Boolean trc = BRepFeat_GettraceFEAT();
719     if (trc) {
720       cout << "LocOpe_DPrism::BarycCurve()" << endl;
721       cout << " Reversed Spine orientation" << endl;
722     }
723 #endif
724 //    Normale.Reverse();  //cts20871
725   }
726   gp_Vec Vec = dz*Normale.XYZ();
727
728   gp_Pnt bar(0., 0., 0.);
729   TColgp_SequenceOfPnt spt;
730   if(!myFirstShape.IsNull()) {
731     LocOpe::SampleEdges(myFirstShape,spt);
732   }
733   else {
734     LocOpe::SampleEdges(mySpine,spt);
735   }
736   for (Standard_Integer jj=1;jj<=spt.Length(); jj++) {
737     const gp_Pnt& pvt = spt(jj);
738     bar.ChangeCoord() += pvt.XYZ();
739   }
740   bar.ChangeCoord().Divide(spt.Length());
741   gp_Ax1 newAx(bar,Vec);
742   Handle(Geom_Line) theLin = new Geom_Line(newAx);
743   return theLin;
744 }