00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef __C_G4NURBS__
00040 #define __C_G4NURBS__ 1
00041
00042 #include "globals.hh"
00043 #include "G4Visible.hh"
00044
00045
00046
00047 #include "G4ios.hh"
00048 #include "G4Point3D.hh"
00049 #include "G4Vector3D.hh"
00050
00051 class G4NURBS : public G4Visible
00052 {
00053 public:
00054
00055
00056
00057
00058
00059
00060 virtual const char* Whoami() const = 0;
00061
00062
00063
00064
00065 virtual ~G4NURBS();
00066
00067
00068
00069
00070
00071 enum t_direction
00072 {
00073 U = 0,
00074 V = 1,
00075 DMask = 1,
00076 NofD = 2
00077 };
00078
00079
00080 static char Tochar(t_direction in_dir);
00081
00082
00083
00084 typedef unsigned int t_index;
00085
00086
00087 typedef t_index t_indKnot;
00088
00089
00090 typedef unsigned int t_indCoord;
00091 typedef unsigned int t_indCtrlPt;
00092 typedef t_index t_inddCtrlPt;
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 enum { X, Y, Z, W, NofC };
00107
00108
00109
00110 typedef G4double t_doubleCtrlPt [NofC];
00111 typedef G4float t_floatCtrlPt [NofC];
00112
00113
00114 G4int GetUorder() const;
00115 G4int GetVorder() const;
00116 G4int GetUnbrKnots() const;
00117 G4int GetVnbrKnots() const;
00118 G4int GetUnbrCtrlPts() const;
00119 G4int GetVnbrCtrlPts() const;
00120 G4int GettotalnbrCtrlPts() const;
00121
00122 G4double GetUmin() const;
00123 G4double GetUmax() const;
00124 G4double GetVmin() const;
00125 G4double GetVmax() const;
00126 void CalcPoint(G4double u, G4double v,
00127 G4Point3D &p, G4Vector3D &utan, G4Vector3D &vtan) const;
00128
00129
00130
00131
00132 G4int Getorder(t_direction in_dir) const;
00133 G4int GetnbrKnots(t_direction in_dir) const;
00134 G4int GetnbrCtrlPts(t_direction in_dir) const;
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 G4float GetfloatKnot(t_direction in_dir, t_indKnot in_index) const;
00145 G4double GetdoubleKnot(t_direction in_dir, t_indKnot in_index) const;
00146 t_floatCtrlPt* GetfloatCtrlPt(t_indCtrlPt in_onedimindex) const;
00147 t_floatCtrlPt* GetfloatCtrlPt(t_inddCtrlPt in_Uindex,
00148 t_inddCtrlPt in_Vindex) const;
00149 t_doubleCtrlPt* GetdoubleCtrlPt(t_indCtrlPt in_onedimindex) const;
00150 t_doubleCtrlPt* GetdoubleCtrlPt(t_inddCtrlPt in_Uindex,
00151 t_inddCtrlPt in_Vindex) const;
00152
00153
00154
00155
00156
00157 G4float* GetfloatAllKnots(t_direction in_dir) const;
00158 G4double* GetdoubleAllKnots(t_direction in_dir) const;
00159 G4float* GetfloatAllCtrlPts() const;
00160 G4double* GetdoubleAllCtrlPts() const;
00161
00162
00163
00164 protected:
00165
00166
00167
00168 typedef Float G4Float;
00169
00170 public:
00171
00172
00173 typedef t_index t_order;
00174
00175
00176 typedef G4Float t_Knot;
00177
00178 protected:
00179
00180
00181 typedef G4Float t_Coord;
00182 typedef t_Coord t_CtrlPt [NofC];
00183
00184
00185
00186
00187
00188 public:
00189
00190
00191
00192
00193
00194
00195
00196 class KnotsIterator;
00197 class CtrlPtsCoordsIterator;
00198 class CtrlPtsIterator;
00199
00200
00201 friend class KnotsIterator;
00202 friend class CtrlPtsCoordsIterator;
00203 friend class CtrlPtsIterator;
00204
00205
00206
00207
00208
00209
00210
00211
00212 class KnotsIterator
00213 {
00214 public:
00215 KnotsIterator(const G4NURBS & in_rNurb, t_direction in_dir,
00216 t_indKnot in_startIndex = 0);
00217 G4bool pick(G4double * inout_pDbl);
00218 G4bool pick(G4float * inout_pFlt);
00219
00220
00221 protected:
00222 const t_direction kmdir;
00223 const t_Knot * const kmpMax;
00224 const t_Knot * mp;
00225 };
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 class CtrlPtsCoordsIterator
00237 {
00238 public:
00239 CtrlPtsCoordsIterator(const G4NURBS & in_rNurb,
00240 t_indCtrlPt in_startCtrlPtIndex = 0);
00241 G4bool pick(G4double * inout_pDbl);
00242 G4bool pick(G4float * inout_pFlt);
00243
00244
00245 protected:
00246 const t_Coord * const kmpMax;
00247 const t_Coord * mp;
00248 };
00249
00250
00251
00252 class CtrlPtsIterator
00253 {
00254 public:
00255 CtrlPtsIterator(const G4NURBS & in_rNurb, t_indCtrlPt in_startIndex = 0);
00256 G4bool pick(t_doubleCtrlPt * inout_pDblCtrlPt);
00257 G4bool pick(t_floatCtrlPt * inout_pFltCtrlPt);
00258
00259
00260 protected:
00261 const t_CtrlPt * const kmpMax;
00262 const t_CtrlPt * mp;
00263 };
00264
00265
00266
00267 protected:
00268
00269
00270 struct t_Dir
00271 {
00272 t_order order;
00273 t_inddCtrlPt nbrCtrlPts;
00274 t_indKnot nbrKnots;
00275 t_Knot * pKnots;
00276
00277 };
00278
00279
00280 typedef enum { NOcheck, check } t_CheckFlag;
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 G4NURBS (t_order in_Uorder, t_order in_Vorder,
00292 t_inddCtrlPt in_UnbrCtrlPts, t_inddCtrlPt in_VnbrCtrlPts,
00293 t_CtrlPt * in_pCtrlPts,
00294 t_Knot * in_pUKnots = 0, t_Knot * in_pVKnots = 0,
00295 t_CheckFlag in_CheckFlag = check );
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 public:
00317
00318
00319 enum t_KnotVectorGenFlag
00320 {
00321 UserDefined,
00322
00323
00324 Regular,
00325
00326
00327
00328 RegularRep
00329
00330
00331 };
00332
00333 protected:
00334
00335
00336
00337
00338 friend std::ostream & operator << (std::ostream & inout_OutStream,
00339 t_KnotVectorGenFlag in_KVGFlag);
00340
00341 G4NURBS (t_order in_Uorder, t_order in_Vorder,
00342 t_inddCtrlPt in_UnbrCtrlPts, t_inddCtrlPt in_VnbrCtrlPts,
00343 t_KnotVectorGenFlag in_UKVGFlag = Regular,
00344 t_KnotVectorGenFlag in_VKVGFlag = Regular,
00345 t_CheckFlag in_CheckFlag = check );
00346
00347
00348 t_Dir m[NofD];
00349 t_indCtrlPt mtotnbrCtrlPts;
00350 t_CtrlPt * mpCtrlPts;
00351
00352
00353
00354 t_indCtrlPt To1d(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const;
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 static t_floatCtrlPt* TofloatCtrlPt(const t_CtrlPt &);
00367
00368
00369 static t_doubleCtrlPt* TodoubleCtrlPt(const t_CtrlPt &);
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 static G4bool MakeKnotVector(t_Dir & inout_dirdat,
00386 t_KnotVectorGenFlag in_KVGFlag);
00387 static G4bool MakeKnotVector(t_Dir * p_inoutdirdat,
00388 t_KnotVectorGenFlag in_KVGFlag);
00389
00390 static void CP(G4NURBS::t_CtrlPt & rcp, t_Coord x, t_Coord y,
00391 t_Coord z, t_Coord w);
00392 static void CP(G4NURBS::t_CtrlPt & rcp, t_Coord x, t_Coord y,
00393 t_Coord z, t_Coord w, G4Float factor);
00394
00395 private:
00396
00397
00398
00399
00400 void Conscheck() const;
00401
00402
00403
00404 G4NURBS(const G4NURBS &);
00405
00406
00407
00408 G4NURBS& operator= (const G4NURBS&);
00409
00410 };
00411
00412
00413 std::ostream & operator << (std::ostream & inout_OutStream,
00414 G4NURBS::t_KnotVectorGenFlag in_KVGFlag);
00415
00416
00417
00418
00419
00420
00421 std::ostream & operator << (std::ostream & inout_outStream,
00422 const G4NURBS & in_kNurb);
00423
00424
00425
00426
00427
00428
00429
00430
00431 inline G4int G4NURBS::GetUorder() const { return m[U].order; }
00432 inline G4int G4NURBS::GetVorder() const { return m[V].order; }
00433 inline G4int G4NURBS::GetUnbrKnots() const { return m[U].nbrKnots; }
00434 inline G4int G4NURBS::GetVnbrKnots() const { return m[V].nbrKnots; }
00435 inline G4int G4NURBS::GetUnbrCtrlPts() const { return m[U].nbrCtrlPts; }
00436 inline G4int G4NURBS::GetVnbrCtrlPts() const { return m[V].nbrCtrlPts; }
00437 inline G4int G4NURBS::GettotalnbrCtrlPts() const { return mtotnbrCtrlPts; }
00438
00439 inline G4double G4NURBS::GetUmin() const {
00440 return (G4double) m[U].pKnots[GetUorder()-1];
00441 }
00442
00443 inline G4double G4NURBS::GetUmax() const {
00444 return (G4double) m[U].pKnots[GetUnbrCtrlPts()];
00445 }
00446
00447 inline G4double G4NURBS::GetVmin() const {
00448 return (G4double) m[V].pKnots[GetVorder()-1];
00449 }
00450
00451 inline G4double G4NURBS::GetVmax() const {
00452 return (G4double) m[V].pKnots[GetVnbrCtrlPts()];
00453 }
00454
00455 inline G4int G4NURBS::Getorder(G4NURBS::t_direction in_dir) const {
00456 return m[in_dir & DMask].order;
00457 }
00458
00459 inline G4int G4NURBS::GetnbrKnots(G4NURBS::t_direction in_dir) const {
00460 return m[in_dir & DMask].nbrKnots;
00461 }
00462
00463 inline G4int G4NURBS::GetnbrCtrlPts(G4NURBS::t_direction in_dir) const {
00464 return m[in_dir & DMask].nbrCtrlPts;
00465 }
00466
00467 inline char G4NURBS::Tochar(G4NURBS::t_direction in_dir) {
00468 return (in_dir != U? 'V': 'U');
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 inline G4NURBS::t_indCtrlPt
00481 G4NURBS::To1d(t_inddCtrlPt in_Uindex, t_inddCtrlPt in_Vindex) const
00482 {
00483 return in_Uindex + in_Vindex*m[U].nbrCtrlPts;
00484 }
00485
00486
00487 inline G4NURBS::t_floatCtrlPt*
00488 G4NURBS::TofloatCtrlPt(const t_CtrlPt & in_krcp)
00489 {
00490 G4NURBS::t_floatCtrlPt * pcopy = new G4NURBS::t_floatCtrlPt [1];
00491 for (G4int indCoord = X; indCoord < NofC; indCoord++)
00492 (*pcopy)[indCoord] = (G4float)in_krcp[indCoord];
00493 return pcopy;
00494 }
00495
00496
00497 inline G4NURBS::t_doubleCtrlPt*
00498 G4NURBS::TodoubleCtrlPt(const t_CtrlPt & in_krcp)
00499 {
00500 G4NURBS::t_doubleCtrlPt * pcopy = new G4NURBS::t_doubleCtrlPt [4];
00501 for (G4int indCoord = X; indCoord < NofC; indCoord++)
00502 (*pcopy)[indCoord] = (G4double)in_krcp[indCoord];
00503 return pcopy;
00504 }
00505
00506
00507 inline G4bool G4NURBS::MakeKnotVector(G4NURBS::t_Dir * p_inoutdirdat,
00508 G4NURBS::t_KnotVectorGenFlag in_KVGFlag)
00509 {
00510 return MakeKnotVector(*p_inoutdirdat, in_KVGFlag);
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520 inline void G4NURBS::CP(G4NURBS::t_CtrlPt & rcp,
00521 t_Coord x, t_Coord y, t_Coord z, t_Coord w)
00522 {
00523 rcp[G4NURBS::X]=x;
00524 rcp[G4NURBS::Y]=y;
00525 rcp[G4NURBS::Z]=z;
00526 rcp[G4NURBS::W]=w;
00527 }
00528
00529
00530 inline void G4NURBS::CP(G4NURBS::t_CtrlPt & rcp, t_Coord x,
00531 t_Coord y, t_Coord z, t_Coord w, G4Float factor)
00532 {
00533 rcp[G4NURBS::X]=factor*x;
00534 rcp[G4NURBS::Y]=factor*y;
00535 rcp[G4NURBS::Z]=factor*z;
00536 rcp[G4NURBS::W]=factor*w;
00537 }
00538
00539 #endif