1 // Created on: 1997-12-05
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1997-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_CurveAndTrihedron.hxx>
18 
19 #include <Adaptor3d_Curve.hxx>
20 #include <GeomFill_LocationLaw.hxx>
21 #include <GeomFill_TrihedronLaw.hxx>
22 #include <GeomLib.hxx>
23 #include <gp_Circ.hxx>
24 #include <gp_Mat.hxx>
25 #include <gp_Pnt.hxx>
26 #include <gp_Vec.hxx>
27 #include <Precision.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <Standard_Type.hxx>
30 #include <TColStd_SequenceOfReal.hxx>
31 
IMPLEMENT_STANDARD_RTTIEXT(GeomFill_CurveAndTrihedron,GeomFill_LocationLaw)32 IMPLEMENT_STANDARD_RTTIEXT(GeomFill_CurveAndTrihedron,GeomFill_LocationLaw)
33 
34 //==================================================================
35 //Function: Create
36 //Purpose :
37 //==================================================================
38 GeomFill_CurveAndTrihedron::GeomFill_CurveAndTrihedron(
39        const Handle(GeomFill_TrihedronLaw)& Trihedron )
40 {
41   myLaw = Trihedron;
42   myCurve.Nullify();
43   Trans.SetIdentity();
44   WithTrans = Standard_False;
45 }
46 
47 //==================================================================
48 //Function: Copy
49 //Purpose :
50 //==================================================================
Handle(GeomFill_LocationLaw)51 Handle(GeomFill_LocationLaw) GeomFill_CurveAndTrihedron::Copy() const
52 {
53   Handle(GeomFill_TrihedronLaw) law;
54   law = myLaw->Copy();
55   Handle(GeomFill_CurveAndTrihedron) copy =
56     new (GeomFill_CurveAndTrihedron) (myLaw->Copy());
57   copy->SetCurve(myCurve);
58   copy->SetTrsf(Trans);
59   return copy;
60 }
61 
62 //==================================================================
63 //Function: SetCurve
64 //Purpose :
65 //==================================================================
SetCurve(const Handle (Adaptor3d_Curve)& C)66  void GeomFill_CurveAndTrihedron::SetCurve(const Handle(Adaptor3d_Curve)& C)
67 {
68   myCurve = C;
69   myTrimmed = C;
70   myLaw->SetCurve(C);
71 }
72 
Handle(Adaptor3d_Curve)73  const Handle(Adaptor3d_Curve)& GeomFill_CurveAndTrihedron::GetCurve() const
74 {
75   return myCurve;
76 }
77 
78 
79 //==================================================================
80 //Function: SetTrsf
81 //Purpose :
82 //==================================================================
SetTrsf(const gp_Mat & Transfo)83  void GeomFill_CurveAndTrihedron::SetTrsf(const gp_Mat& Transfo)
84 {
85   Trans = Transfo;
86   gp_Mat Aux;
87   Aux.SetIdentity();
88   Aux -= Trans;
89   WithTrans = Standard_False; // Au cas ou Trans = I
90   for (Standard_Integer ii=1; ii<=3 && !WithTrans ; ii++)
91     for (Standard_Integer jj=1; jj<=3 && !WithTrans; jj++)
92       if (Abs(Aux.Value(ii, jj)) > 1.e-14)  WithTrans = Standard_True;
93 }
94 
95 //==================================================================
96 //Function: D0
97 //Purpose :
98 //==================================================================
D0(const Standard_Real Param,gp_Mat & M,gp_Vec & V)99  Standard_Boolean GeomFill_CurveAndTrihedron::D0(const Standard_Real Param,
100 						 gp_Mat& M,
101 						 gp_Vec& V)
102 {
103   Standard_Boolean Ok;
104   myTrimmed->D0(Param, Point);
105   V.SetXYZ(Point.XYZ());
106 
107   Ok = myLaw->D0(Param, V1, V2, V3);
108   M.SetCols(V2.XYZ(), V3.XYZ(), V1.XYZ());
109 
110   if (WithTrans) {
111     M *= Trans;
112   }
113   return Ok;
114 }
115 
116 //==================================================================
117 //Function: D0
118 //Purpose :
119 //==================================================================
D0(const Standard_Real Param,gp_Mat & M,gp_Vec & V,TColgp_Array1OfPnt2d &)120  Standard_Boolean GeomFill_CurveAndTrihedron::D0(const Standard_Real Param,
121 						 gp_Mat& M,
122 						 gp_Vec& V,
123 						 TColgp_Array1OfPnt2d&)
124 {
125   Standard_Boolean Ok;
126   myTrimmed->D0(Param, Point);
127   V.SetXYZ(Point.XYZ());
128 
129   Ok = myLaw->D0(Param, V1, V2, V3);
130   M.SetCols(V2.XYZ(), V3.XYZ(), V1.XYZ());
131 
132   if (WithTrans) {
133     M *= Trans;
134   }
135   return Ok;
136 }
137 
138 //==================================================================
139 //Function:
140 //Purpose :
141 //==================================================================
D1(const Standard_Real Param,gp_Mat & M,gp_Vec & V,gp_Mat & DM,gp_Vec & DV,TColgp_Array1OfPnt2d &,TColgp_Array1OfVec2d &)142  Standard_Boolean GeomFill_CurveAndTrihedron::D1(const Standard_Real Param,
143 						 gp_Mat& M,
144 						 gp_Vec& V,
145 						 gp_Mat& DM,
146 						 gp_Vec& DV,
147 						 TColgp_Array1OfPnt2d& ,
148 						 TColgp_Array1OfVec2d& )
149 {
150   Standard_Boolean Ok;
151   myTrimmed->D1(Param, Point, DV);
152   V.SetXYZ(Point.XYZ());
153 
154   gp_Vec DV1, DV2, DV3;
155   Ok = myLaw->D1(Param,
156 		 V1, DV1,
157 		 V2, DV2,
158                  V3, DV3);
159   M.SetCols( V2.XYZ(),  V3.XYZ(),  V1.XYZ());
160   DM.SetCols(DV2.XYZ(), DV3.XYZ(), DV1.XYZ());
161 
162   if (WithTrans) {
163     M *= Trans;
164     DM *= Trans;
165   }
166 
167   return Ok;
168 }
169 
170 //==================================================================
171 //Function:
172 //Purpose :
173 //==================================================================
D2(const Standard_Real Param,gp_Mat & M,gp_Vec & V,gp_Mat & DM,gp_Vec & DV,gp_Mat & D2M,gp_Vec & D2V,TColgp_Array1OfPnt2d &,TColgp_Array1OfVec2d &,TColgp_Array1OfVec2d &)174  Standard_Boolean GeomFill_CurveAndTrihedron::D2(const Standard_Real Param,
175 						 gp_Mat& M,
176 						 gp_Vec& V,
177 						 gp_Mat& DM,
178 						 gp_Vec& DV,
179 						 gp_Mat& D2M,
180 						 gp_Vec& D2V,
181 						 TColgp_Array1OfPnt2d&,
182 						 TColgp_Array1OfVec2d&,
183 						 TColgp_Array1OfVec2d&)
184 {
185  Standard_Boolean Ok;
186  myTrimmed->D2(Param, Point, DV, D2V);
187  V.SetXYZ(Point.XYZ());
188 
189  gp_Vec DV1, DV2, DV3;
190  gp_Vec D2V1, D2V2, D2V3;
191  Ok = myLaw->D2(Param,
192                 V1, DV1, D2V1,
193 		V2,DV2,  D2V2,
194 		V3, DV3, D2V3);
195 
196  M.  SetCols(V2.XYZ(),   V3.XYZ(),   V1.XYZ());
197  DM. SetCols(DV2.XYZ(),  DV3.XYZ(),  DV1.XYZ());
198  D2M.SetCols(D2V2.XYZ(), D2V3.XYZ(), D2V1.XYZ());
199 
200   if (WithTrans) {
201     M *= Trans;
202     DM *= Trans;
203     D2M *= Trans;
204   }
205 
206  return Ok;
207 }
208 
209 //==================================================================
210 //Function:
211 //Purpose :
212 //==================================================================
NbIntervals(const GeomAbs_Shape S) const213  Standard_Integer GeomFill_CurveAndTrihedron::NbIntervals(const GeomAbs_Shape S) const
214 {
215   Standard_Integer Nb_Sec, Nb_Law;
216   Nb_Sec  =  myTrimmed->NbIntervals(S);
217   Nb_Law  =  myLaw->NbIntervals(S);
218 
219   if  (Nb_Sec==1) {
220     return Nb_Law;
221   }
222   else if (Nb_Law==1) {
223     return Nb_Sec;
224   }
225 
226   TColStd_Array1OfReal IntC(1, Nb_Sec+1);
227   TColStd_Array1OfReal IntL(1, Nb_Law+1);
228   TColStd_SequenceOfReal    Inter;
229   myTrimmed->Intervals(IntC, S);
230   myLaw->Intervals(IntL, S);
231 
232   GeomLib::FuseIntervals( IntC, IntL, Inter, Precision::PConfusion()*0.99);
233   return Inter.Length()-1;
234 }
235 //==================================================================
236 //Function:
237 //Purpose :
238 //==================================================================
Intervals(TColStd_Array1OfReal & T,const GeomAbs_Shape S) const239  void GeomFill_CurveAndTrihedron::Intervals(TColStd_Array1OfReal& T,
240 					    const GeomAbs_Shape S) const
241 {
242   Standard_Integer Nb_Sec, Nb_Law;
243   Nb_Sec  =  myTrimmed->NbIntervals(S);
244   Nb_Law  =  myLaw->NbIntervals(S);
245 
246   if  (Nb_Sec==1) {
247     myLaw->Intervals(T, S);
248     return;
249   }
250   else if (Nb_Law==1) {
251     myTrimmed->Intervals(T, S);
252     return;
253   }
254 
255   TColStd_Array1OfReal IntC(1, Nb_Sec+1);
256   TColStd_Array1OfReal IntL(1, Nb_Law+1);
257   TColStd_SequenceOfReal    Inter;
258   myTrimmed->Intervals(IntC, S);
259   myLaw->Intervals(IntL, S);
260 
261   GeomLib::FuseIntervals(IntC, IntL, Inter, Precision::PConfusion()*0.99);
262   for (Standard_Integer ii=1; ii<=Inter.Length(); ii++)
263     T(ii) = Inter(ii);
264 }
265 //==================================================================
266 //Function:
267 //Purpose :
268 //==================================================================
SetInterval(const Standard_Real First,const Standard_Real Last)269  void GeomFill_CurveAndTrihedron::SetInterval(const Standard_Real First,
270 					      const Standard_Real Last)
271 {
272   myLaw->SetInterval( First, Last);
273   myTrimmed = myCurve->Trim( First, Last, 0);
274 }
275 //==================================================================
276 //Function: GetInterval
277 //Purpose :
278 //==================================================================
GetInterval(Standard_Real & First,Standard_Real & Last) const279  void GeomFill_CurveAndTrihedron::GetInterval(Standard_Real& First,
280 					      Standard_Real& Last) const
281 {
282   First =  myTrimmed->FirstParameter();
283   Last =   myTrimmed->LastParameter();
284 }
285 
286 //==================================================================
287 //Function: GetDomain
288 //Purpose :
289 //==================================================================
GetDomain(Standard_Real & First,Standard_Real & Last) const290  void GeomFill_CurveAndTrihedron::GetDomain(Standard_Real& First,
291 					    Standard_Real& Last) const
292 {
293   First =  myCurve->FirstParameter();
294   Last =   myCurve->LastParameter();
295 }
296 
297 //==================================================================
298 //Function:
299 //Purpose : GetMaximalNorm
300 //          On suppose les triedre normee => return 1
301 //==================================================================
GetMaximalNorm()302  Standard_Real GeomFill_CurveAndTrihedron::GetMaximalNorm()
303 {
304   return 1.;
305 }
306 //==================================================================
307 //Function:
308 //Purpose :
309 //==================================================================
GetAverageLaw(gp_Mat & AM,gp_Vec & AV)310  void GeomFill_CurveAndTrihedron::GetAverageLaw(gp_Mat& AM,
311 						gp_Vec& AV)
312 {
313   Standard_Integer ii;
314   Standard_Real U, delta;
315   gp_Vec V;
316 
317   myLaw->GetAverageLaw(V1, V2, V3);
318   AM.SetCols(V1.XYZ(), V2.XYZ(), V3.XYZ());
319 
320   AV.SetCoord(0., 0., 0.);
321   delta = (myTrimmed->LastParameter() - myTrimmed->FirstParameter())/10;
322   U=  myTrimmed->FirstParameter();
323   for (ii=0; ii<=10; ii++, U+=delta) {
324     V.SetXYZ( myTrimmed->Value(U).XYZ() );
325     AV += V;
326   }
327   AV /= 11;
328 }
329 
330 
331 //==================================================================
332 //Function : IsTranslation
333 //Purpose :
334 //==================================================================
IsTranslation(Standard_Real & Error) const335  Standard_Boolean GeomFill_CurveAndTrihedron::IsTranslation(Standard_Real& Error) const
336 {
337   GeomAbs_CurveType Type;
338   Error = 0;
339   Type = myCurve->GetType();
340   if (Type == GeomAbs_Line) {
341     return (myLaw->IsConstant() || myLaw->IsOnlyBy3dCurve());
342   }
343   return Standard_False;
344 }
345 
346 
347 //==================================================================
348 //Function : IsRotation
349 //Purpose :
350 //==================================================================
IsRotation(Standard_Real & Error) const351  Standard_Boolean GeomFill_CurveAndTrihedron::IsRotation(Standard_Real& Error)  const
352 {
353   GeomAbs_CurveType Type;
354   Error = 0;
355   Type = myCurve->GetType();
356   if (Type == GeomAbs_Circle) {
357     return myLaw->IsOnlyBy3dCurve();
358   }
359   return Standard_False;
360 }
361 
362 //==================================================================
363 //Function : Rotation
364 //Purpose :
365 //==================================================================
Rotation(gp_Pnt & Centre) const366  void GeomFill_CurveAndTrihedron::Rotation(gp_Pnt& Centre)  const
367 {
368 //  GeomAbs_CurveType Type;
369 //  Type = myCurve->GetType();
370   Centre =  myCurve->Circle().Location();
371 }
372