1 // Created on: 1998-08-17
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-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 <Convert_ParameterisationType.hxx>
19 #include <GCPnts_AbscissaPoint.hxx>
20 #include <Geom_BSplineCurve.hxx>
21 #include <Geom_BSplineSurface.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Geometry.hxx>
24 #include <Geom_Surface.hxx>
25 #include <GeomAdaptor_Curve.hxx>
26 #include <GeomConvert.hxx>
27 #include <GeomFill_EvolvedSection.hxx>
28 #include <gp_Pnt.hxx>
29 #include <Law_Function.hxx>
30 #include <Precision.hxx>
31 #include <Standard_OutOfRange.hxx>
32 #include <Standard_Type.hxx>
33 #include <TColgp_Array2OfPnt.hxx>
34 #include <TColStd_Array1OfInteger.hxx>
35 #include <TColStd_Array1OfReal.hxx>
36 
37 #include <stdio.h>
38 IMPLEMENT_STANDARD_RTTIEXT(GeomFill_EvolvedSection,GeomFill_SectionLaw)
39 
40 #ifdef DRAW
41 #include <DrawTrSurf.hxx>
42 #include <Geom_Curve.hxx>
43 #include <Geom_BSplineCurve.hxx>
44 static Standard_Integer NumSec = 0;
45 static Standard_Boolean Affich = 0;
46 #endif
47 
GeomFill_EvolvedSection(const Handle (Geom_Curve)& C,const Handle (Law_Function)& L)48 GeomFill_EvolvedSection::GeomFill_EvolvedSection(const Handle(Geom_Curve)& C,
49 						 const Handle(Law_Function)& L)
50 {
51   L->Bounds(First, Last);
52   mySection = Handle(Geom_Curve)::DownCast(C->Copy());
53   myLaw =  L->Trim(First, Last, 1.e-20);
54   TLaw = myLaw;
55   myCurve =  Handle(Geom_BSplineCurve)::DownCast(C);
56   if (myCurve.IsNull()) {
57     myCurve = GeomConvert::CurveToBSplineCurve(C, Convert_QuasiAngular);
58     if (myCurve->IsPeriodic()) {
59       Standard_Integer M = myCurve->Degree()/2+1;
60       myCurve->RemoveKnot(1, M, Precision::Confusion());
61     }
62   }
63 
64 #ifdef DRAW
65   if (Affich) {
66     char name[256];
67     sprintf(name,"UnifSect_%d",++NumSec);
68     DrawTrSurf::Set(name, myCurve);
69   }
70 #endif
71 }
72 
73 //=======================================================
74 // Purpose :D0
75 //=======================================================
D0(const Standard_Real U,TColgp_Array1OfPnt & Poles,TColStd_Array1OfReal & Weights)76  Standard_Boolean GeomFill_EvolvedSection::D0(const Standard_Real U,
77 					      TColgp_Array1OfPnt& Poles,
78 					      TColStd_Array1OfReal& Weights)
79 {
80   Standard_Real val;
81   Standard_Integer ii, L =  Poles.Length();
82   val= TLaw->Value(U);
83   myCurve->Poles(Poles);
84   for (ii=1; ii<=L; ii++) {
85     Poles(ii).ChangeCoord() *= val;
86   }
87   myCurve->Weights(Weights);
88 
89   return Standard_True;
90 }
91 
92 //=======================================================
93 // Purpose :D1
94 //=======================================================
D1(const Standard_Real U,TColgp_Array1OfPnt & Poles,TColgp_Array1OfVec & DPoles,TColStd_Array1OfReal & Weights,TColStd_Array1OfReal & DWeights)95  Standard_Boolean GeomFill_EvolvedSection::D1(const Standard_Real U,
96 					      TColgp_Array1OfPnt& Poles,
97 					      TColgp_Array1OfVec& DPoles,
98 					      TColStd_Array1OfReal& Weights,
99 					      TColStd_Array1OfReal& DWeights)
100 {
101  Standard_Real val, dval;
102  Standard_Integer ii, L =  Poles.Length();
103  TLaw->D1(U, val, dval);
104 
105  myCurve->Poles(Poles);
106  myCurve->Weights(Weights);
107  for (ii=1; ii<=L; ii++) {
108    DPoles(ii).SetXYZ(Poles(ii).XYZ());
109    DPoles(ii) *= dval;
110    Poles(ii).ChangeCoord() *= val;
111  }
112  DWeights.Init(0);
113 
114  return Standard_True;
115 }
116 
117 //=======================================================
118 // Purpose :D2
119 //=======================================================
D2(const Standard_Real U,TColgp_Array1OfPnt & Poles,TColgp_Array1OfVec & DPoles,TColgp_Array1OfVec & D2Poles,TColStd_Array1OfReal & Weights,TColStd_Array1OfReal & DWeights,TColStd_Array1OfReal & D2Weights)120  Standard_Boolean GeomFill_EvolvedSection::D2(const Standard_Real U,
121 					      TColgp_Array1OfPnt& Poles,
122 					      TColgp_Array1OfVec& DPoles,
123 					      TColgp_Array1OfVec& D2Poles,
124 					      TColStd_Array1OfReal& Weights,
125 					      TColStd_Array1OfReal& DWeights,
126 					      TColStd_Array1OfReal& D2Weights)
127 {
128   Standard_Real val, dval, d2val;
129   Standard_Integer ii, L =  Poles.Length();
130   TLaw->D2(U, val, dval, d2val);
131   myCurve->Poles(Poles);
132   myCurve->Weights(Weights);
133 
134   for (ii=1; ii<=L; ii++) {
135     DPoles(ii).SetXYZ(Poles(ii).XYZ());
136     D2Poles(ii) = DPoles(ii);
137     D2Poles(ii) *= d2val;
138     DPoles(ii)  *= dval;
139     Poles(ii).ChangeCoord() *= val;
140   }
141 
142   DWeights.Init(0);
143   D2Weights.Init(0);
144 
145   return Standard_True;
146 }
147 
148 //=======================================================
149 // Purpose :BSplineSurface()
150 //=======================================================
Handle(Geom_BSplineSurface)151  Handle(Geom_BSplineSurface) GeomFill_EvolvedSection::BSplineSurface() const
152 {
153 /*  Standard_Integer ii, NbPoles = myCurve->NbPoles();
154   TColgp_Array2OfPnt Poles( 1, NbPoles, 1, 2);
155   TColStd_Array1OfReal UKnots(1,myCurve->NbKnots()), VKnots(1,2);
156   TColStd_Array1OfInteger UMults(1,myCurve->NbKnots()), VMults(1,2);
157 
158   for (ii=1; ii <= NbPoles; ii++) {
159     Poles(ii, 1) =  Poles(ii, 2) = myCurve->Pole(ii);
160   }
161 
162   myCurve->Knots(UKnots);
163   VKnots(1) = First;
164   VKnots(2) = Last;
165 
166   myCurve->Multiplicities(UMults);
167   VMults.Init(2);
168 
169 
170   Handle(Geom_BSplineSurface) BS =
171     new (Geom_BSplineSurface) ( Poles,
172 			       UKnots, VKnots,
173 			       UMults, VMults,
174 			       myCurve->Degree(), 1,
175 			       myCurve->IsPeriodic());*/
176   Handle(Geom_BSplineSurface) BS;
177   BS.Nullify();
178   return BS;
179 
180 }
181 //=======================================================
182 // Purpose :SectionShape
183 //=======================================================
SectionShape(Standard_Integer & NbPoles,Standard_Integer & NbKnots,Standard_Integer & Degree) const184  void GeomFill_EvolvedSection::SectionShape(Standard_Integer& NbPoles,
185 					    Standard_Integer& NbKnots,
186 					    Standard_Integer& Degree) const
187 {
188    NbPoles = myCurve->NbPoles();
189    NbKnots = myCurve->NbKnots();
190    Degree  = myCurve->Degree();
191 }
192 
Knots(TColStd_Array1OfReal & TKnots) const193  void GeomFill_EvolvedSection::Knots(TColStd_Array1OfReal& TKnots) const
194 {
195  myCurve->Knots(TKnots);
196 }
197 //=======================================================
198 // Purpose :Mults
199 //=======================================================
Mults(TColStd_Array1OfInteger & TMults) const200  void GeomFill_EvolvedSection::Mults(TColStd_Array1OfInteger& TMults) const
201 {
202    myCurve->Multiplicities(TMults);
203 }
204 
205 
206 //=======================================================
207 // Purpose :IsRational
208 //=======================================================
IsRational() const209  Standard_Boolean GeomFill_EvolvedSection::IsRational() const
210 {
211   return myCurve->IsRational();
212 }
213 
214 //=======================================================
215 // Purpose :IsUPeriodic
216 //=======================================================
IsUPeriodic() const217  Standard_Boolean GeomFill_EvolvedSection::IsUPeriodic() const
218 {
219   return myCurve->IsPeriodic();
220 }
221 
222 //=======================================================
223 // Purpose :IsVPeriodic
224 //=======================================================
IsVPeriodic() const225  Standard_Boolean GeomFill_EvolvedSection::IsVPeriodic() const
226 {
227   return
228     (Abs(myLaw->Value(First) - myLaw->Value(Last)) < Precision::Confusion());
229 }
230 
231 //=======================================================
232 // Purpose :NbIntervals
233 //=======================================================
NbIntervals(const GeomAbs_Shape S) const234  Standard_Integer GeomFill_EvolvedSection::NbIntervals(const GeomAbs_Shape S) const
235 {
236   return myLaw->NbIntervals(S) ;
237 }
238 
239 
240 //=======================================================
241 // Purpose :Intervals
242 //=======================================================
Intervals(TColStd_Array1OfReal & T,const GeomAbs_Shape S) const243  void GeomFill_EvolvedSection::Intervals(TColStd_Array1OfReal& T,
244 					 const GeomAbs_Shape S) const
245 {
246   myLaw->Intervals(T, S) ;
247 }
248 
249 
250 //=======================================================
251 // Purpose : SetInterval
252 //=======================================================
SetInterval(const Standard_Real F,const Standard_Real L)253  void GeomFill_EvolvedSection::SetInterval(const Standard_Real F,
254 					   const Standard_Real L)
255 {
256  TLaw = myLaw->Trim(F, L, Precision::PConfusion());
257 }
258 
259 //=======================================================
260 // Purpose : GetInterval
261 //=======================================================
GetInterval(Standard_Real & F,Standard_Real & L) const262  void GeomFill_EvolvedSection::GetInterval(Standard_Real& F,
263 					   Standard_Real& L) const
264 {
265   TLaw->Bounds(F, L);
266 }
267 
268 //=======================================================
269 // Purpose : GetDomain
270 //=======================================================
GetDomain(Standard_Real & F,Standard_Real & L) const271  void GeomFill_EvolvedSection::GetDomain(Standard_Real& F,
272 					 Standard_Real& L) const
273 {
274   F = First;
275   L = Last;
276 }
277 
278 //=======================================================
279 // Purpose : GetTolerance
280 //=======================================================
GetTolerance(const Standard_Real BoundTol,const Standard_Real SurfTol,const Standard_Real,TColStd_Array1OfReal & Tol3d) const281  void GeomFill_EvolvedSection::GetTolerance(const Standard_Real BoundTol,
282 					    const Standard_Real SurfTol,
283 //					    const Standard_Real AngleTol,
284 					    const Standard_Real ,
285 					    TColStd_Array1OfReal& Tol3d) const
286 {
287   Tol3d.Init(SurfTol);
288   if (BoundTol<SurfTol) {
289     Tol3d(Tol3d.Lower()) = BoundTol;
290     Tol3d(Tol3d.Upper()) = BoundTol;
291   }
292 }
293 
294 //=======================================================
295 // Purpose :
296 //=======================================================
BarycentreOfSurf() const297  gp_Pnt GeomFill_EvolvedSection::BarycentreOfSurf() const
298 {
299   Standard_Real U = mySection->FirstParameter(), Delta, b;
300   Standard_Integer ii;
301   gp_Pnt P, Bary;
302 
303   Delta = ( myCurve->LastParameter() - U ) / 20;
304   Bary.SetCoord(0., 0., 0.);
305   for (ii=0 ; ii <=20; ii++, U+=Delta) {
306     P = myCurve->Value(U);
307     Bary.ChangeCoord() += P.XYZ();
308   }
309 
310   U = First;
311   Delta = ( Last - First) / 20;
312   for (ii=0, b=0.0; ii <=20; ii++, U+=Delta) {
313     b += myLaw->Value(U);
314   }
315   Bary.ChangeCoord() *= b/(21*21);
316   return Bary;
317 }
318 
MaximalSection() const319  Standard_Real GeomFill_EvolvedSection::MaximalSection() const
320 {
321   Standard_Real L, val, max, U, Delta;
322   Standard_Integer ii;
323   GeomAdaptor_Curve AC (mySection);
324   L = GCPnts_AbscissaPoint::Length(AC);
325 
326   Delta = ( Last - First) / 20;
327   for (ii=0, max=0.0, U = First; ii <=20; ii++, U+=Delta) {
328     val = myLaw->Value(U);
329     if (val>max) max = val;
330   }
331   return L*max;
332 }
333 
GetMinimalWeight(TColStd_Array1OfReal & Weights) const334 void GeomFill_EvolvedSection::GetMinimalWeight(TColStd_Array1OfReal& Weights) const
335 {
336   if (myCurve->IsRational()) {
337     myCurve->Weights(Weights);
338   }
339   else {
340     Weights.Init(1);
341   }
342 }
343 
IsConstant(Standard_Real & Error) const344  Standard_Boolean GeomFill_EvolvedSection::IsConstant(Standard_Real& Error) const
345 {
346 //  Standard_Real isconst = Standard_False;
347   Standard_Boolean isconst = Standard_False;
348   Error = 0.;
349   return isconst;
350 }
351 
Handle(Geom_Curve)352  Handle(Geom_Curve) GeomFill_EvolvedSection::ConstantSection() const
353 {
354   Standard_Real Err, scale;
355   if (!IsConstant(Err)) throw StdFail_NotDone("The Law is not Constant!");
356   gp_Trsf T;
357   gp_Pnt P(0, 0, 0);
358   scale = myLaw->Value(First) +
359           myLaw->Value((First+Last)/2) +
360           myLaw->Value(Last);
361   T.SetScale(P, scale/3);
362 
363   Handle(Geom_Curve) C;
364   C = Handle(Geom_Curve)::DownCast( mySection->Copy());
365   C->Transform(T);
366   return C;
367 }
368 
369 
370 
371