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