0026252: GeomAdaptor_Surface should use inner adaptor to calculate values of complex...
[occt.git] / src / BRepSweep / BRepSweep_Translation.cxx
1 // Created on: 1993-02-04
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <GeomAdaptor_SurfaceOfLinearExtrusion.hxx>
19 #include <BRep_CurveRepresentation.hxx>
20 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21 #include <BRep_TEdge.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 #include <BRepSweep_Translation.hxx>
26 #include <BRepTools.hxx>
27 #include <ElSLib.hxx>
28 #include <Geom2d_Line.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_CylindricalSurface.hxx>
31 #include <Geom_Line.hxx>
32 #include <Geom_Plane.hxx>
33 #include <Geom_Surface.hxx>
34 #include <Geom_SurfaceOfLinearExtrusion.hxx>
35 #include <GeomAbs_SurfaceType.hxx>
36 #include <GeomAdaptor_Curve.hxx>
37 #include <GeomAdaptor_HCurve.hxx>
38 #include <GeomAdaptor_Surface.hxx>
39 #include <gp.hxx>
40 #include <gp_Dir.hxx>
41 #include <gp_Dir2d.hxx>
42 #include <gp_Lin.hxx>
43 #include <gp_Lin2d.hxx>
44 #include <gp_Pnt.hxx>
45 #include <gp_Pnt2d.hxx>
46 #include <gp_Trsf.hxx>
47 #include <gp_Vec.hxx>
48 #include <Precision.hxx>
49 #include <Standard_ConstructionError.hxx>
50 #include <Sweep_NumShape.hxx>
51 #include <TopExp_Explorer.hxx>
52 #include <TopLoc_Location.hxx>
53 #include <TopoDS.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS_Vertex.hxx>
56
57 static void SetThePCurve(const BRep_Builder& B,
58                          TopoDS_Edge& E,
59                          const TopoDS_Face& F,
60                          const TopAbs_Orientation O,
61                          const Handle(Geom2d_Curve)& C)
62 {
63   // check if there is already a pcurve on non planar faces
64   Standard_Real f,l;
65   Handle(Geom2d_Curve) OC;
66   TopLoc_Location SL;
67   Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
68   if (GP.IsNull())
69     OC = BRep_Tool::CurveOnSurface(E,F,f,l);
70   if (OC.IsNull()) 
71     B.UpdateEdge(E,C,F,Precision::Confusion());
72   else {
73     if (O == TopAbs_REVERSED) 
74       B.UpdateEdge(E,OC,C,F,Precision::Confusion());
75     else 
76       B.UpdateEdge(E,C,OC,F,Precision::Confusion());
77   }
78 }
79
80 //=======================================================================
81 //function : BRepSweep_Translation
82 //purpose  : 
83 //=======================================================================
84
85 BRepSweep_Translation::BRepSweep_Translation(const TopoDS_Shape& S, 
86                                              const Sweep_NumShape& N,
87                                              const TopLoc_Location& L,
88                                              const gp_Vec& V, 
89                                              const Standard_Boolean C,
90                                              const Standard_Boolean Canonize) :
91        BRepSweep_Trsf(BRep_Builder(),S,N,L,C),
92        myVec(V),
93        myCanonize(Canonize)
94 {
95
96   Standard_ConstructionError_Raise_if
97     (V.Magnitude()<Precision::Confusion(),
98      "BRepSweep_Translation::Constructor");
99   Init();
100 }
101
102 //=======================================================================
103 //function : MakeEmptyVertex
104 //purpose  : 
105 //=======================================================================
106
107 TopoDS_Shape  BRepSweep_Translation::MakeEmptyVertex
108   (const TopoDS_Shape& aGenV, 
109    const Sweep_NumShape& aDirV)
110 {
111   //Only called when the option of construction is with copy.
112   Standard_ConstructionError_Raise_if
113     (!myCopy,"BRepSweep_Translation::MakeEmptyVertex");
114   gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aGenV));
115   if (aDirV.Index()==2) P.Transform(myLocation.Transformation());
116   TopoDS_Vertex V;
117   ////// modified by jgv, 5.10.01, for buc61008 //////
118   //myBuilder.Builder().MakeVertex(V,P,Precision::Confusion());
119   myBuilder.Builder().MakeVertex( V, P, BRep_Tool::Tolerance(TopoDS::Vertex(aGenV)) );
120   ////////////////////////////////////////////////////
121   return V;
122 }
123
124
125 //=======================================================================
126 //function : MakeEmptyDirectingEdge
127 //purpose  : 
128 //=======================================================================
129
130 TopoDS_Shape  BRepSweep_Translation::MakeEmptyDirectingEdge
131   (const TopoDS_Shape& aGenV, 
132    const Sweep_NumShape&)
133 {
134   gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aGenV));
135   gp_Lin L(P,myVec);
136   Handle(Geom_Line) GL = new Geom_Line(L);
137   TopoDS_Edge E;
138   myBuilder.Builder().MakeEdge
139     (E,GL,BRep_Tool::Tolerance(TopoDS::Vertex(aGenV)));
140   return E;
141 }
142
143
144 //=======================================================================
145 //function : MakeEmptyGeneratingEdge
146 //purpose  : 
147 //=======================================================================
148
149 TopoDS_Shape  BRepSweep_Translation::MakeEmptyGeneratingEdge
150   (const TopoDS_Shape& aGenE, 
151    const Sweep_NumShape& aDirV)
152 {
153   //Call only in case of construction with copy.
154   Standard_ConstructionError_Raise_if
155     (!myCopy,"BRepSweep_Translation::MakeEmptyVertex");
156   TopoDS_Edge newE;
157   if(BRep_Tool::Degenerated(TopoDS::Edge(aGenE)))
158   {
159     myBuilder.Builder().MakeEdge(newE);
160     myBuilder.Builder().UpdateEdge(newE, BRep_Tool::Tolerance(TopoDS::Edge(aGenE)));
161     myBuilder.Builder().Degenerated(newE, Standard_True);
162   }
163   else
164   {
165     TopLoc_Location L;
166     Standard_Real First,Last;
167     Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(aGenE),L,First,Last);
168     if(!C.IsNull())
169     {
170       C = Handle(Geom_Curve)::DownCast(C->Copy());
171       C->Transform(L.Transformation());
172       if (aDirV.Index() == 2) C->Transform(myLocation.Transformation());
173     }
174     myBuilder.Builder().MakeEdge
175       (newE,C,BRep_Tool::Tolerance(TopoDS::Edge(aGenE)));
176   }
177   return newE;
178 }
179
180
181 //=======================================================================
182 //function : SetParameters
183 //purpose  : 
184 //=======================================================================
185
186 void  BRepSweep_Translation::SetParameters
187   (const TopoDS_Shape& aNewFace, 
188    TopoDS_Shape& aNewVertex, 
189    const TopoDS_Shape& aGenF, 
190    const TopoDS_Shape& aGenV, 
191    const Sweep_NumShape&)
192 {
193   //Glue the parameter of vertices directly included in cap faces.
194   gp_Pnt2d pnt2d = BRep_Tool::Parameters(TopoDS::Vertex(aGenV),
195                                          TopoDS::Face(aGenF));
196   myBuilder.Builder().UpdateVertex
197     (TopoDS::Vertex(aNewVertex),pnt2d.X(),pnt2d.Y(),
198      TopoDS::Face(aNewFace),Precision::PConfusion());
199 }
200
201
202 //=======================================================================
203 //function : SetDirectingParameter
204 //purpose  : 
205 //=======================================================================
206
207 void  BRepSweep_Translation::SetDirectingParameter
208   (const TopoDS_Shape& aNewEdge, 
209    TopoDS_Shape& aNewVertex, 
210    const TopoDS_Shape&, 
211    const Sweep_NumShape&, 
212    const Sweep_NumShape& aDirV)
213 {
214   Standard_Real param = 0;
215   if (aDirV.Index() == 2) param = myVec.Magnitude();
216   myBuilder.Builder().UpdateVertex(TopoDS::Vertex(aNewVertex),
217                                    param,TopoDS::Edge(aNewEdge),
218                                    Precision::PConfusion());
219 }
220
221
222 //=======================================================================
223 //function : SetGeneratingParameter
224 //purpose  : 
225 //=======================================================================
226
227 void  BRepSweep_Translation::SetGeneratingParameter
228   (const TopoDS_Shape& aNewEdge, 
229    TopoDS_Shape& aNewVertex, 
230    const TopoDS_Shape& aGenE, 
231    const TopoDS_Shape& aGenV, 
232    const Sweep_NumShape&)
233 {
234   TopoDS_Vertex vbid = TopoDS::Vertex(aNewVertex); 
235   vbid.Orientation(aGenV.Orientation());
236   myBuilder.Builder().UpdateVertex
237     (vbid,
238      BRep_Tool::Parameter(TopoDS::Vertex(aGenV),TopoDS::Edge(aGenE)),
239      TopoDS::Edge(aNewEdge),Precision::PConfusion());
240 }
241
242
243 //=======================================================================
244 //function : MakeEmptyFace
245 //purpose  : 
246 //=======================================================================
247
248 TopoDS_Shape  BRepSweep_Translation::MakeEmptyFace
249   (const TopoDS_Shape& aGenS, 
250    const Sweep_NumShape& aDirS)
251 {
252   Standard_Real toler;
253   TopoDS_Face F;
254   Handle(Geom_Surface) S;
255   if (myDirShapeTool.Type(aDirS)==TopAbs_EDGE){
256     TopLoc_Location L;
257     Standard_Real First,Last;
258     Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(aGenS),L,First,Last);
259     toler = BRep_Tool::Tolerance(TopoDS::Edge(aGenS));
260     gp_Trsf Tr = L.Transformation();
261     C = Handle(Geom_Curve)::DownCast(C->Copy());
262     //extruded surfaces are inverted correspondingly to the topology, so reverse.
263     C->Transform(Tr);
264     gp_Dir D(myVec);
265     D.Reverse();
266
267     if (myCanonize) {
268       Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve(C,First,Last);
269       GeomAdaptor_SurfaceOfLinearExtrusion AS(HC,D);
270       switch(AS.GetType()){
271
272       case GeomAbs_Plane :
273         S = new Geom_Plane(AS.Plane());
274         break;
275       case GeomAbs_Cylinder :
276         S = new Geom_CylindricalSurface(AS.Cylinder());
277         break;
278       default:
279         S = new Geom_SurfaceOfLinearExtrusion(C,D);
280         break;
281       }
282     }
283     else {
284       S = new Geom_SurfaceOfLinearExtrusion(C,D);
285     }
286   }
287   else {
288     TopLoc_Location L;
289     S = BRep_Tool::Surface(TopoDS::Face(aGenS),L);
290     toler = BRep_Tool::Tolerance(TopoDS::Face(aGenS));
291     gp_Trsf Tr = L.Transformation();
292     S = Handle(Geom_Surface)::DownCast(S->Copy());
293     S->Transform(Tr);
294     if (aDirS.Index()==2) S->Translate(myVec);
295   }
296   myBuilder.Builder().MakeFace(F,S,toler);
297   return F;
298 }
299
300
301 //=======================================================================
302 //function : SetPCurve
303 //purpose  : 
304 //=======================================================================
305
306 void  BRepSweep_Translation::SetPCurve
307   (const TopoDS_Shape& aNewFace, 
308    TopoDS_Shape& aNewEdge, 
309    const TopoDS_Shape& aGenF, 
310    const TopoDS_Shape& aGenE, 
311    const Sweep_NumShape&,
312    const TopAbs_Orientation)
313 {
314   //Set on edges of cap faces the same pcurves as 
315   //edges of the generating face.
316   Standard_Boolean isclosed = BRep_Tool::IsClosed(TopoDS::Edge(aGenE), TopoDS::Face(aGenF));
317   if(isclosed)
318   {
319     Standard_Real First, Last;
320     TopoDS_Edge anE = TopoDS::Edge(aGenE.Oriented(TopAbs_FORWARD));
321     Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(anE, TopoDS::Face(aGenF), First, Last);
322     anE.Reverse();
323     Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(anE, TopoDS::Face(aGenF), First, Last);
324     myBuilder.Builder().UpdateEdge(TopoDS::Edge(aNewEdge), aC1, aC2, TopoDS::Face(aNewFace),Precision::PConfusion());
325   }
326   else
327   {
328     Standard_Real First,Last;
329     myBuilder.Builder().UpdateEdge(TopoDS::Edge(aNewEdge),
330       BRep_Tool::CurveOnSurface(TopoDS::Edge(aGenE),TopoDS::Face(aGenF),First,Last),
331          TopoDS::Face(aNewFace),Precision::PConfusion());
332   }
333 }
334
335
336 //=======================================================================
337 //function : SetGeneratingPCurve
338 //purpose  : 
339 //=======================================================================
340
341 void  BRepSweep_Translation::SetGeneratingPCurve
342   (const TopoDS_Shape& aNewFace, 
343    TopoDS_Shape& aNewEdge, 
344    const TopoDS_Shape& , 
345    const Sweep_NumShape&, 
346    const Sweep_NumShape& aDirV,
347    const TopAbs_Orientation orien)
348 {
349   TopLoc_Location Loc;
350   GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewFace),Loc));
351 //  Standard_Real First,Last;
352   gp_Lin2d L;
353   TopoDS_Edge aNewOrientedEdge = TopoDS::Edge(aNewEdge);
354   aNewOrientedEdge.Orientation(orien);
355
356   if (AS.GetType()==GeomAbs_Plane){
357 /* nothing is done JAG
358     gp_Pln pln = AS.Plane();
359     gp_Ax3 ax3 = pln.Position();
360
361 // JYL : the following produces bugs on an edge constructed from a trimmed 3D curve :
362 //
363 //    Handle(Geom_Line) 
364 //      GL = Handle(Geom_Line)::DownCast(BRep_Tool::Curve(TopoDS::Edge(aGenE),
365 //                                                      Loc,First,Last));
366 //    gp_Lin gl = GL->Lin();
367 //    gl.Transform(Loc.Transformation());
368 //
369 // correction :
370     const TopoDS_Edge& EE = TopoDS::Edge(aGenE);
371     BRepAdaptor_Curve BRAC(EE);
372     gp_Lin gl = BRAC.Line();
373
374     if(aDirV.Index()==2) gl.Translate(myVec);
375     gp_Pnt pnt = gl.Location();
376     gp_Dir dir = gl.Direction();
377     Standard_Real u,v;
378     ElSLib::PlaneParameters(ax3,pnt,u,v);
379     gp_Pnt2d pnt2d(u,v);
380     gp_Dir2d dir2d(dir.Dot(ax3.XDirection()),dir.Dot(ax3.YDirection()));
381     L.SetLocation(pnt2d);
382     L.SetDirection(dir2d);
383 */
384   }
385   else{
386     Standard_Real v = 0;
387     if (aDirV.Index() == 2) v = -myVec.Magnitude();
388     L.SetLocation(gp_Pnt2d(0,v));
389     L.SetDirection(gp_Dir2d(1,0));
390 //  }
391   Handle(Geom2d_Line) GL = new Geom2d_Line(L);
392   SetThePCurve(myBuilder.Builder(),
393                TopoDS::Edge(aNewEdge),
394                TopoDS::Face(aNewFace),
395                orien,
396                GL);
397   }
398 }
399
400
401 //=======================================================================
402 //function : SetDirectingPCurve
403 //purpose  : 
404 //=======================================================================
405
406 void  BRepSweep_Translation::SetDirectingPCurve
407   (const TopoDS_Shape& aNewFace, 
408    TopoDS_Shape& aNewEdge, 
409    const TopoDS_Shape& aGenE, 
410    const TopoDS_Shape& aGenV, 
411    const Sweep_NumShape&,
412    const TopAbs_Orientation orien)
413 {
414   TopLoc_Location Loc;
415   GeomAdaptor_Surface AS(BRep_Tool::Surface(TopoDS::Face(aNewFace),Loc));
416   gp_Lin2d L;
417   if(AS.GetType()!=GeomAbs_Plane){
418     L.SetLocation(gp_Pnt2d(BRep_Tool::Parameter(TopoDS::Vertex(aGenV),
419                                                 TopoDS::Edge(aGenE)),0));
420     L.SetDirection(gp_Dir2d(0,-1));
421 /* JAG
422   }
423   else{
424
425     gp_Pln pln = AS.Plane();
426     gp_Ax3 ax3 = pln.Position();
427     gp_Pnt pv = BRep_Tool::Pnt(TopoDS::Vertex(aGenV));
428     gp_Dir dir(myVec);
429     Standard_Real u,v;
430     ElSLib::PlaneParameters(ax3,pv,u,v);
431     gp_Pnt2d pnt2d(u,v);
432     gp_Dir2d dir2d(dir.Dot(ax3.XDirection()),dir.Dot(ax3.YDirection()));
433     L.SetLocation(pnt2d);
434     L.SetDirection(dir2d);
435     
436   }
437 */
438   Handle(Geom2d_Line) GL = new Geom2d_Line(L);
439   SetThePCurve(myBuilder.Builder(),
440                TopoDS::Edge(aNewEdge),
441                TopoDS::Face(aNewFace),
442                orien,GL);
443   }
444 }
445
446 //=======================================================================
447 //function : DirectSolid
448 //purpose  : 
449 //=======================================================================
450
451 TopAbs_Orientation BRepSweep_Translation::DirectSolid
452   (const TopoDS_Shape& aGenS,
453    const Sweep_NumShape&)
454 {
455   // compare the face normal and the direction
456   BRepAdaptor_Surface surf(TopoDS::Face(aGenS));
457   gp_Pnt P;
458   gp_Vec du,dv;
459   surf.D1((surf.FirstUParameter() + surf.LastUParameter()) / 2.,
460           (surf.FirstVParameter() + surf.LastVParameter()) / 2.,
461           P,du,dv);
462     
463   Standard_Real x = myVec.DotCross(du,dv);
464   TopAbs_Orientation orient = (x > 0) ? TopAbs_REVERSED : TopAbs_FORWARD;
465   return orient;
466 }
467
468
469 //=======================================================================
470 //function : GGDShapeIsToAdd
471 //purpose  : 
472 //=======================================================================
473
474 Standard_Boolean BRepSweep_Translation::GGDShapeIsToAdd
475   (const TopoDS_Shape& ,
476    const TopoDS_Shape& ,
477    const TopoDS_Shape& ,
478    const TopoDS_Shape& ,
479    const Sweep_NumShape&  )const
480 {
481   return Standard_True;
482 }
483
484
485 //=======================================================================
486 //function : GDDShapeIsToAdd
487 //purpose  : 
488 //=======================================================================
489
490 Standard_Boolean BRepSweep_Translation::GDDShapeIsToAdd
491   (const TopoDS_Shape& ,
492    const TopoDS_Shape& ,
493    const TopoDS_Shape& ,
494    const Sweep_NumShape& ,
495    const Sweep_NumShape&  )const
496 {
497   return Standard_True;
498 }
499
500
501 //=======================================================================
502 //function : SeparatedWires
503 //purpose  : 
504 //=======================================================================
505
506 Standard_Boolean BRepSweep_Translation::SeparatedWires
507   (const TopoDS_Shape& ,
508    const TopoDS_Shape& ,
509    const TopoDS_Shape& ,
510    const TopoDS_Shape& ,
511    const Sweep_NumShape&  )const
512 {
513   return Standard_False;
514 }
515
516
517 //=======================================================================
518 //function : HasShape
519 //purpose  : 
520 //=======================================================================
521
522 Standard_Boolean  BRepSweep_Translation::HasShape
523   (const TopoDS_Shape& aGenS, 
524    const Sweep_NumShape& aDirS)const 
525 {
526   if(myDirShapeTool.Type(aDirS) == TopAbs_EDGE) {
527  
528     if(myGenShapeTool.Type(aGenS) == TopAbs_EDGE) {
529       TopoDS_Edge E = TopoDS::Edge(aGenS);
530
531       // check if the edge is degenerated 
532       if(BRep_Tool::Degenerated(E)) {
533         return Standard_False;
534       }
535       // check if the edge is a sewing edge  
536
537 //  modified by NIZHNY-EAP Fri Dec 24 11:13:09 1999 ___BEGIN___
538 //      const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
539
540 //      BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
541 //      BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
542     
543 //      while (itcr.More()) {
544 //      const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
545 //      if (cr->IsCurveOnSurface() && 
546 //          cr->IsCurveOnClosedSurface() )      {
547 //        cout<<"sewing edge"<<endl;
548 //        return Standard_False;
549 //      }
550 //      itcr.Next();
551 //      }
552       TopExp_Explorer FaceExp(myGenShape, TopAbs_FACE);
553       for (;FaceExp.More(); FaceExp.Next()) {
554         TopoDS_Face F = TopoDS::Face(FaceExp.Current());
555         if (BRepTools::IsReallyClosed(E, F))
556           return Standard_False;
557       }
558 //  modified by NIZHNY-EAP Fri Dec 24 11:13:21 1999 ___END___
559     }
560   }
561   
562   return Standard_True;
563 }
564
565 //=======================================================================
566 //function : IsInvariant
567 //purpose  : 
568 //=======================================================================
569
570 Standard_Boolean  BRepSweep_Translation::IsInvariant
571   (const TopoDS_Shape& )const 
572 {
573   return Standard_False;
574 }
575
576
577 //=======================================================================
578 //function : Vec
579 //purpose  : 
580 //=======================================================================
581
582 gp_Vec BRepSweep_Translation::Vec()const
583 {
584   return myVec;
585 }
586
587