0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / GeomFill / GeomFill_BoundWithSurf.cxx
1 // Created on: 1995-10-19
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1995-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 <GeomFill_BoundWithSurf.ixx>
18 #include <Law.hxx>
19 #include <Law_BSpFunc.hxx>
20 #include <Adaptor3d_HSurface.hxx>
21 #include <Adaptor2d_HCurve2d.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <gp_Vec2d.hxx>
24 //=======================================================================
25 //function : GeomFill_BoundWithSurf
26 //purpose  : 
27 //=======================================================================
28
29 GeomFill_BoundWithSurf::GeomFill_BoundWithSurf
30 (const Adaptor3d_CurveOnSurface& CurveOnSurf,
31  const Standard_Real           Tol3d,
32  const Standard_Real           Tolang) :
33  GeomFill_Boundary(Tol3d,Tolang), myConS(CurveOnSurf)
34 {
35 }
36
37
38 //=======================================================================
39 //function : Value
40 //purpose  : 
41 //=======================================================================
42
43 gp_Pnt GeomFill_BoundWithSurf::Value(const Standard_Real U) const 
44 {
45   Standard_Real x = U;
46   if(!myPar.IsNull()) x = myPar->Value(U);
47   return myConS.Value(x);
48 }
49
50
51 //=======================================================================
52 //function : D1
53 //purpose  : 
54 //=======================================================================
55
56 void GeomFill_BoundWithSurf::D1(const Standard_Real U, 
57                                 gp_Pnt& P, 
58                                 gp_Vec& V) const 
59 {
60   Standard_Real x = U, dx = 1.;
61   if(!myPar.IsNull()) myPar->D1(U,x,dx);
62   myConS.D1(x, P, V);
63   V.Multiply(dx);
64 }
65
66
67 //=======================================================================
68 //function : HasNormals
69 //purpose  : 
70 //=======================================================================
71
72 Standard_Boolean GeomFill_BoundWithSurf::HasNormals() const 
73 {
74   return Standard_True;
75 }
76
77
78 //=======================================================================
79 //function : Norm
80 //purpose  : 
81 //=======================================================================
82
83 gp_Vec GeomFill_BoundWithSurf::Norm(const Standard_Real U) const 
84 {
85   // voir s il ne faudrait pas utiliser LProp ou autre.
86   if (!HasNormals()) 
87     Standard_Failure::Raise("BoundWithSurf Norm : pas de contrainte");
88
89 //  Handle(Adaptor3d_HSurface)& S = myConS.GetSurface();
90 //  Handle(Adaptor2d_HCurve2d)& C2d = myConS.GetCurve();
91   Standard_Real x,y;
92   Standard_Real w = U;
93   if(!myPar.IsNull()) w = myPar->Value(U);
94   myConS.GetCurve()->Value(w).Coord(x,y);
95   gp_Pnt P;
96   gp_Vec Su, Sv;
97   myConS.GetSurface()->D1(x,y,P,Su,Sv);
98   Su.Cross(Sv);
99   Su.Normalize();
100   return Su;
101 }
102
103
104 //=======================================================================
105 //function : D1Norm
106 //purpose  : 
107 //=======================================================================
108
109 void GeomFill_BoundWithSurf::D1Norm(const Standard_Real U,
110                                     gp_Vec&             N,
111                                     gp_Vec&             DN) const 
112 {
113   if (!HasNormals()) 
114     Standard_Failure::Raise("BoundWithSurf Norm : pas de contrainte");
115 //  Handle(Adaptor3d_HSurface)& S = myConS.GetSurface();
116 //  Handle(Adaptor2d_HCurve2d)& C2d = myConS.GetCurve();
117   gp_Pnt2d P2d;
118   gp_Vec2d V2d;
119   Standard_Real x,y,dx,dy;
120   Standard_Real w = U, dw = 1.;
121   if(!myPar.IsNull()) myPar->D1(U,w,dw);
122   myConS.GetCurve()->D1(w,P2d,V2d);
123   P2d.Coord(x,y);
124   V2d.Multiply(dw);
125   V2d.Coord(dx,dy);
126   gp_Pnt P;
127   gp_Vec Su, Sv, Suu, Suv, Svv;
128   myConS.GetSurface()->D2(x,y,P,Su,Sv, Suu, Svv, Suv);
129   N = Su.Crossed(Sv);
130   N.Normalize();
131   Standard_Real nsuu = N.Dot(Suu), nsuv = N.Dot(Suv), nsvv = N.Dot(Svv);
132   Standard_Real susu = Su.Dot(Su), susv = Su.Dot(Sv), svsv = Sv.Dot(Sv);
133   Standard_Real deno = (susu*svsv) - (susv*susv);
134   if(Abs(deno) < 1.e-16) {
135     // on embraye sur un calcul approche, c est mieux que rien!?!
136     gp_Vec temp = Norm(U + 1.e-12);
137     DN = N.Multiplied(-1.);
138     DN.Add(temp);
139     DN.Multiply(1.e-12);
140   }
141   else{
142     Standard_Real a = (-nsuu*svsv + nsuv*susv)/deno;
143     Standard_Real b = ( nsuu*susv - nsuv*susu)/deno;
144     Standard_Real c = (-nsuv*svsv + nsvv*susv)/deno;
145     Standard_Real d = ( nsuv*susv - nsvv*susu)/deno;
146
147     gp_Vec temp1 = Su.Multiplied(a);
148     gp_Vec temp2 = Sv.Multiplied(b);
149     temp1.Add(temp2);
150     temp2        = Su.Multiplied(c);
151     gp_Vec temp3 = Sv.Multiplied(d);
152     temp2.Add(temp3);
153     temp1.Multiply(dx);
154     temp2.Multiply(dy);
155     DN = temp1.Added(temp2);
156   }
157 }
158
159
160 //=======================================================================
161 //function : Reparametrize
162 //purpose  : 
163 //=======================================================================
164
165 void GeomFill_BoundWithSurf::Reparametrize(const Standard_Real First, 
166                                            const Standard_Real Last,
167                                            const Standard_Boolean HasDF, 
168                                            const Standard_Boolean HasDL, 
169                                            const Standard_Real DF, 
170                                            const Standard_Real DL,
171                                            const Standard_Boolean Rev)
172 {
173   Handle(Law_BSpline) curve = Law::Reparametrize(myConS,
174                                                  First,Last,
175                                                  HasDF,HasDL,DF,DL,
176                                                  Rev,30);
177   myPar = new Law_BSpFunc();
178   Handle(Law_BSpFunc)::DownCast (myPar)->SetCurve(curve);
179 }
180
181 //=======================================================================
182 //function : Bounds
183 //purpose  : 
184 //=======================================================================
185
186 void GeomFill_BoundWithSurf::Bounds(Standard_Real& First, 
187                                     Standard_Real& Last) const 
188 {
189   if(!myPar.IsNull()) myPar->Bounds(First,Last);
190   else{
191     First = myConS.FirstParameter();
192     Last  = myConS.LastParameter();
193   }
194 }
195
196
197 //=======================================================================
198 //function : IsDegenerated
199 //purpose  : 
200 //=======================================================================
201
202 Standard_Boolean GeomFill_BoundWithSurf::IsDegenerated() const 
203 {
204   return Standard_False;
205 }