G4BezierSurface Class Reference

#include <G4BezierSurface.hh>

Inheritance diagram for G4BezierSurface:

G4Surface G4STEPEntity

Public Member Functions

 G4BezierSurface ()
virtual ~G4BezierSurface ()
G4Point3D AveragePoint () const
void SetAveragePoint (G4Point3D p)
G4double UAverage () const
G4double VAverage () const
void Dir (G4int d)
void ChangeDir ()
G4double SMin () const
G4double SMax () const
G4int GetOrder (G4int direction) const
void PutOrder (G4int direction, G4int value)
G4double GetU () const
G4double GetV () const
void CalcBBox ()
G4int BIntersect (G4SurfaceList &)
G4int ClipBothDirs ()
void ClipSurface ()
virtual G4Vector3D SurfaceNormal (const G4Point3D &Pt) const

Protected Attributes

G4SurfaceListbezier_list

Static Protected Attributes

static G4int Clips = 0
static G4int Splits = 0
static G4double Tolerance = 0

Friends

class G4BSplineSurface
class G4ProjectedSurface
void CopySurface (G4BezierSurface &bez)

Detailed Description

Definition at line 51 of file G4BezierSurface.hh.


Constructor & Destructor Documentation

G4BezierSurface::G4BezierSurface (  ) 

Definition at line 48 of file G4BezierSurface.cc.

00049   : G4Surface(), bezier_list(0), smin(0.), smax(0.),
00050     average_u(0.), average_v(0.), dir(0), u_knots(0), v_knots(0),
00051     ctl_points(0), new_knots(0), ord(0), oslo_m(0), lower(0), upper(0),
00052     u_min(0.), u_max(0.), v_min(0.), v_max(0.), old_points(0)
00053 {
00054   order[0]=0; order[1]=0;
00055   u[0]=0.; u[1]=0.;
00056   v[0]=0.; v[1]=0.;
00057 }

G4BezierSurface::~G4BezierSurface (  )  [virtual]

Definition at line 59 of file G4BezierSurface.cc.

References G4Surface::bbox, and G4OsloMatrix::GetNextNode().

00060 {
00061   delete u_knots;
00062   delete v_knots;
00063   delete new_knots;
00064   delete ctl_points;
00065   delete old_points;
00066   
00067   G4OsloMatrix* temp_oslo = oslo_m;
00068   
00069   while(oslo_m != (G4OsloMatrix*)0)
00070   {
00071     oslo_m = oslo_m->GetNextNode();
00072     delete temp_oslo;
00073     temp_oslo = oslo_m;
00074   }
00075 
00076   delete oslo_m;
00077   delete bbox;
00078 }


Member Function Documentation

G4Point3D G4BezierSurface::AveragePoint (  )  const [inline]

Definition at line 38 of file G4BezierSurface.icc.

Referenced by G4BSplineSurface::Intersect().

00039 {
00040   return average_pt;
00041 }

G4int G4BezierSurface::BIntersect ( G4SurfaceList  ) 

Definition at line 211 of file G4BezierSurface.cc.

References G4Surface::bbox, bezier_list, CalcBBox(), ClipSurface(), G4KnotVector::GetKnot(), G4KnotVector::GetSize(), G4BoundingBox3D::GetTestResult(), and Tolerance.

00212 {
00213   bezier_list = &bez_list;
00214   G4int clip_regions = 0; // Used for tolerance/efficiency-testing
00215   
00216   do
00217   {
00218     // Calc bbox
00219     CalcBBox();
00220 
00221     // Test bbox
00222 /* L. Broglia
00223     bbox->Test2dBBox();
00224 */
00225     // bbox->Test();
00226 
00227     // Check result
00228     if(!bbox->GetTestResult())
00229       return 0;
00230     
00231     // The first clipping has already been Done
00232     // previously so we continue by doing the
00233     // actual clip.
00234     
00235     // Cut out the clipped region of the surface
00236     GetClippedRegionFromSurface();
00237     clip_regions++;
00238     
00239     // Calculate the knot vectors and control points
00240     // for the clipped surface
00241     RefineSurface();    
00242 
00243     // Gets the u- and v-bounds for the clipped surface
00244     u_min = u_knots->GetKnot(0);        
00245     u_max = u_knots->GetKnot(u_knots->GetSize() - 1);   
00246     v_min = v_knots->GetKnot(0);        
00247     v_max = v_knots->GetKnot(v_knots->GetSize() - 1); 
00248     
00249     // Choose the G4Vector3D for the next() clipping so that
00250     // the larger side will be clipped.  
00251     if( (u_max - u_min) < (v_max - v_min) )     
00252       dir = 1;
00253     else
00254       dir = 0;
00255 
00256     // Calculate the clip points
00257     ClipSurface();
00258     //      G4cout << "\n       SMINMAX : " << smin << "  " << smax; 
00259     
00260     // The ray intersects with the bounding box
00261     // but not with the surface itself.   
00262     if( smin > 1.0 || smax < 0.0 )
00263     {
00264       //            G4cout << "\nG4BezierSurface::Intersect : bezier missed!"; 
00265       //            bezier_list->RemoveSurface(this);
00266       return 0;
00267     }
00268     
00269     if( (smax - smin) > 0.8)
00270     {
00271       // Multiple intersections
00272       //            G4cout << "\nG4BezierSurface::Intersect : Bezier split.";
00273       SplitNURBSurface();
00274       // Now the two new surfaces should also be
00275       // clipped in both G4Vector3Ds i.e the
00276       // last and the second last surface
00277       // in the List. This is Done after returning
00278       // from this function.
00279       //            G4cout << "\n\n  BEZ SPLIT in final Calc! \n\n";
00280 
00281             
00282       return 2;
00283     }
00284     
00285     // Calculate the smin and smax values on the
00286     // b_spline.
00287     LocalizeClipValues();       
00288     
00289     // Check if the size of the remaining surface is within the
00290     // Tolerance .  
00291   } while ((u_max - u_min > Tolerance) || (v_max - v_min) > Tolerance);    
00292   
00293   SetValues();
00294   //    G4cout << "\nG4BezierSurface::Intersect :Regions were cut " 
00295   //           << clip_regions << "  Times.\n";
00296   
00297   return 1;
00298 }

void G4BezierSurface::CalcBBox (  )  [virtual]

Reimplemented from G4Surface.

Definition at line 142 of file G4BezierSurface.cc.

References G4Surface::bbox, G4ControlPoints::Get3D(), G4ControlPoints::GetCols(), G4ControlPoints::GetRows(), and PINFINITY().

Referenced by BIntersect().

00143 {
00144   // Finds the bounds of the 2D-projected nurb iow
00145   // calculates the bounds for a bounding rectangle
00146   // to the surface. The bounding rectangle is used
00147   // for a preliminary check of intersection.
00148   G4Point3D box_min = G4Point3D(PINFINITY);
00149   G4Point3D box_max = G4Point3D(-PINFINITY);
00150  
00151     
00152   // Loop to search the whole control point mesh
00153   // for the minimum and maximum values for.X() and y.
00154   for(register G4int a = ctl_points->GetRows()-1; a>=0;a--)
00155     for(register G4int b = ctl_points->GetCols()-1; b>=0;b--)
00156     {
00157 /* L. Broglia
00158       G4Point2d& tmp = (G4Point2d&)ctl_points->get(a,b);
00159       if((box_min.X()) > (tmp.X())) box_min.X(tmp.X());
00160       if((box_max.X()) < (tmp.X())) box_max.X(tmp.X()); 
00161       if((box_min.Y()) > (tmp.Y())) box_min.Y(tmp.Y()); 
00162       if((box_max.Y()) < (tmp.Y())) box_max.Y(tmp.Y()); 
00163 */
00164       G4Point3D tmp = ctl_points->Get3D(a,b);
00165       if((box_min.x()) > (tmp.x())) box_min.setX(tmp.x());
00166       if((box_max.x()) < (tmp.x())) box_max.setX(tmp.x());      
00167       if((box_min.y()) > (tmp.y())) box_min.setY(tmp.y());      
00168       if((box_max.y()) < (tmp.y())) box_max.setY(tmp.y());    
00169     }
00170         
00171   bbox = new G4BoundingBox3D(box_min, box_max);
00172 }

void G4BezierSurface::ChangeDir (  )  [inline]

Definition at line 68 of file G4BezierSurface.icc.

00069 {
00070   dir=!dir;
00071 }

G4int G4BezierSurface::ClipBothDirs (  ) 

Definition at line 96 of file G4BezierSurface.cc.

References bezier_list, ClipSurface(), COL, G4SurfaceList::RemoveSurface(), and ROW.

00097 {
00098   dir = ROW;
00099   ClipSurface(); 
00100   
00101   //   G4cout << "\n CLIP BOTH DIRS  1: " << smin << "  " << smax;
00102 
00103   if(smin > 1.0 || smax < 0.0)
00104   {
00105     bezier_list->RemoveSurface(this);
00106     return 1;
00107   }
00108   else
00109     if((smax - smin) > 0.8)
00110     {
00111       SplitNURBSurface();
00112       return 0;
00113     }
00114   
00115   LocalizeClipValues();
00116   SetValues();
00117   
00118   // Other G4Vector3D clipping and testing.
00119   dir = COL;
00120   ClipSurface();
00121   //    G4cout << "\n CLIP BOTH DIRS  2: " << smin << "  " << smax;
00122     
00123   if(smin > 1.0 || smax < 0.0)
00124   {
00125     bezier_list->RemoveSurface(this);
00126     return 1;
00127   }
00128   else
00129     if((smax - smin) > 0.8)
00130     {
00131       SplitNURBSurface();
00132       return 0;
00133     }
00134 
00135   LocalizeClipValues();    
00136   SetValues();
00137   CalcAverage();
00138   return 1;
00139 }

void G4BezierSurface::ClipSurface (  ) 

Definition at line 301 of file G4BezierSurface.cc.

References Clips, G4cout, G4ControlPoints::Get3D(), G4ControlPoints::GetCols(), G4ConvexHull::GetMax(), G4ConvexHull::GetMin(), G4ConvexHull::GetNextHull(), G4ConvexHull::GetParam(), G4ControlPoints::GetRows(), G4Surface::kCarTolerance, CLHEP::detail::n, ROW, G4ConvexHull::SetMax(), G4ConvexHull::SetMin(), and G4ConvexHull::SetNextHull().

Referenced by BIntersect(), and ClipBothDirs().

00302 {
00303   // This routine is described in Computer Graphics, Volume 24, 
00304   // Number 4, August 1990 under the title Ray Tracing Trimmed
00305   // Rational Surface Patches.
00306   
00307 
00308   //    G4cout << "\nBezier clip.";
00309   
00310   register G4int i,j;
00311   register G4int col_size = ctl_points->GetCols();
00312   register G4int row_size = ctl_points->GetRows();
00313 
00314   G4ConvexHull *ch_tmp= new G4ConvexHull(0,1.0e8,-1.0e8);
00315   G4ConvexHull *ch_ptr=0, *ch_first=0;
00316   
00317   // The four cornerpoints of the controlpoint mesh.
00318 
00319 /* L. Broglia
00320   G4Point2d pt1 = ctl_points->get(0,0);    
00321   G4Point2d pt2 = ctl_points->get(0,col_size-1);    
00322   G4Point2d pt3 = ctl_points->get(row_size-1,0);    
00323   G4Point2d pt4 = ctl_points->get(row_size-1,col_size-1);    
00324   G4Point2d v1,v2,v3;
00325 */
00326   G4Point3D pt1 = ctl_points->Get3D(0,0);    
00327   G4Point3D pt2 = ctl_points->Get3D(0,col_size-1);    
00328   G4Point3D pt3 = ctl_points->Get3D(row_size-1,0);    
00329   G4Point3D pt4 = ctl_points->Get3D(row_size-1,col_size-1);    
00330   G4Point3D v1,v2,v3;
00331 
00332   if ( dir == ROW)
00333   {
00334     // Vectors from cornerpoints
00335     v1 = (pt1 - pt3);
00336     //  v1.X() = pt1.X() - pt3.X();
00337     //  v1.Y() = pt1.Y() - pt3.Y();
00338     v2 = (pt2 - pt4);
00339     //  v2.X() = pt2.X() - pt4.X();
00340     //  v2.Y() = pt2.Y() - pt4.Y();
00341   } 
00342   else
00343   {
00344     v1 = pt1 - pt2;
00345     v2 = pt3 - pt4;
00346     //  v1.X() = pt1.X() - pt2.X();
00347     //  v1.Y() = pt1.Y() - pt2.Y();
00348     //  v2.X() = pt3.X() - pt4.X();
00349     //  v2.Y() = pt3.Y() - pt4.Y();             
00350   }
00351 /* L. Broglia  
00352   v3.X(v1.X() + v2.X());
00353   v3.Y(v1.Y() + v1.Y());
00354 */
00355   v3 = v1 + v2 ;
00356   
00357   smin =  1.0e8;
00358   smax = -1.0e8;
00359   
00360   G4double norm = std::sqrt(v3.x() * v3.x() + v3.y() * v3.y());
00361   if(!norm)
00362   {
00363     G4cout << "\nNormal zero!";
00364     G4cout << "\nLINE & DIR: " << line.x() << " " << line.y() << "  " << dir; 
00365     G4cout << "\n";
00366     
00367     if((std::abs(line.x())) > kCarTolerance) 
00368       line.setX(-line.x());
00369     else
00370       if((std::abs(line.y())) > kCarTolerance)
00371         line.setY(-line.y());
00372       else
00373       {
00374         G4cout << "\n  RETURNING FROm CLIP..";
00375         smin = 0; smax = 1; delete ch_tmp;
00376         return;
00377       }
00378 
00379     G4cout << "\nCHANGED LINE & DIR: " << line.x() << " " 
00380            << line.y() << "  " << dir;          
00381   }
00382   else
00383   {
00384     line.setX( v3.y() / norm);
00385     line.setY(-v3.x() / norm);
00386   }
00387 
00388   //    smin =  1.0e8;
00389   //    smax = -1.0e8;
00390   //    G4cout << "\n  FINAL LINE & DIR: " << line.X() << " " 
00391   //           << line.Y() << "  " << dir;      
00392   
00393   if( dir == ROW)
00394   {
00395     // Create a Convex() hull List 
00396     for(G4int a = 0; a < col_size; a++)
00397     {
00398       ch_ptr = new G4ConvexHull(a/(col_size - 1.0),1.0e8,-1.0e8);
00399       if(! a) 
00400       {
00401         ch_first=ch_ptr; delete ch_tmp;
00402       }
00403       else ch_tmp->SetNextHull(ch_ptr);
00404       
00405       ch_tmp=ch_ptr;
00406     }
00407     
00408     ch_ptr=ch_first;
00409     register G4double value;
00410     
00411     // Loops through the control point mesh and calculates
00412     // the nvex() hull for the surface.
00413     
00414     for( G4int h = 0; h < row_size; h++)
00415     {
00416       for(G4int k = 0; k < col_size; k++)
00417       {
00418 /* L. Broglia
00419         G4Point2d& coordstmp = (G4Point2d&)ctl_points->get(h,k);  
00420         value = - ((coordstmp.X() * line.X() + coordstmp.Y() * line.Y()));
00421 */
00422         G4Point3D coordstmp = ctl_points->Get3D(h,k);  
00423         value = - ((coordstmp.x() * line.x() + coordstmp.y() * line.y()));
00424 
00425         if( value <= (ch_ptr->GetMin()+kCarTolerance)) ch_ptr->SetMin(value);
00426         if( value >= (ch_ptr->GetMax()-kCarTolerance)) ch_ptr->SetMax(value);
00427             
00428         ch_ptr=ch_ptr->GetNextHull();
00429       }
00430       
00431       ch_ptr=ch_first;
00432     }
00433     
00434     ch_ptr=ch_first;
00435     // Finds the points where the nvex() hull intersects
00436     // with the coordinate .X()is. These points are the
00437     // minimum and maximum values to where to clip the
00438     // surface.
00439     
00440     for(G4int l = 0; l < col_size - 1; l++)
00441     {
00442       ch_tmp=ch_ptr->GetNextHull();
00443       for(G4int q = l+1; q < col_size; q++)
00444       {
00445         register G4double d, param1, param2;
00446         param1 = ch_ptr->GetParam();
00447         param2 = ch_tmp->GetParam();
00448         
00449         if(ch_tmp->GetMax() - ch_ptr->GetMax())
00450         {
00451           d = Findzero( param1, param2, ch_ptr->GetMax(), ch_tmp->GetMax());
00452           if( d <= (smin + kCarTolerance) ) smin = d * .99;
00453           if( d >= (smax - kCarTolerance) ) smax = d * .99 + .01;
00454         }
00455         
00456         if(ch_tmp->GetMin() - ch_ptr->GetMin())
00457         {
00458           d = Findzero( param1, param2, ch_ptr->GetMin(), ch_tmp->GetMin());
00459           if( d <= (smin + kCarTolerance)) smin = d * .99;
00460           if( d >= (smax - kCarTolerance)) smax = d * .99 + .01;
00461         }
00462         
00463         ch_tmp=ch_tmp->GetNextHull();
00464       }
00465       
00466       ch_ptr=ch_ptr->GetNextHull();
00467     }
00468     
00469     ch_ptr=ch_first;
00470 
00471     if (smin <= 0.0)   smin = 0.0;
00472     if (smax >= 1.0)   smax = 1.0;
00473 
00474     if ( (ch_ptr)
00475       && (Sign(ch_ptr->GetMin()) != Sign(ch_ptr->GetMax())))  smin = 0.0;
00476     
00477     i = Sign(ch_tmp->GetMin()); // ch_tmp points to last nvex()_hull in List
00478     j = Sign(ch_tmp->GetMax());
00479     
00480     if ( std::abs(i-j) > kCarTolerance ) smax = 1.0;
00481     //  if ( i != j)  smax = 1.0;
00482     
00483   } 
00484   else // Other G4Vector3D
00485   {
00486     for(G4int n = 0; n < row_size; n++)
00487       {
00488         ch_ptr = new G4ConvexHull(n/(row_size - 1.0),1.0e8,-1.0e8);
00489         if(!n) 
00490         {
00491           ch_first=ch_ptr; delete ch_tmp;
00492         }
00493         else ch_tmp->SetNextHull(ch_ptr);
00494         
00495         ch_tmp=ch_ptr;
00496       }
00497     
00498     ch_ptr=ch_first;
00499     
00500     for( G4int o = 0; o < col_size; o++)
00501     {
00502       for(G4int p = 0; p < row_size; p++)
00503       {
00504         register G4double value;
00505 
00506 /* L. Broglia
00507         G4Point2d& coordstmp =(G4Point2d&) ctl_points->get(p,o);              
00508         value = - ((coordstmp.X() * line.X() + coordstmp.Y() * line.Y()));
00509 */
00510         G4Point3D coordstmp = ctl_points->Get3D(p,o);         
00511         value = - ((coordstmp.x() * line.x() + coordstmp.y() * line.y()));
00512 
00513         if( value <= (ch_ptr->GetMin()+kCarTolerance)) ch_ptr->SetMin(value);
00514         if( value >= (ch_ptr->GetMax()-kCarTolerance)) ch_ptr->SetMax(value);
00515         
00516         ch_ptr=ch_ptr->GetNextHull();
00517       }
00518 
00519       ch_ptr=ch_first;
00520     }
00521     
00522     ch_ptr=ch_first;
00523     delete ch_tmp;
00524     
00525     for(G4int q = 0; q < row_size - 1; q++)
00526     {
00527       ch_tmp=ch_ptr->GetNextHull();
00528       for(G4int r = q+1; r < row_size; r++)
00529       {
00530         register G4double param1 = ch_ptr->GetParam();
00531         register G4double param2 = ch_tmp->GetParam();
00532         register G4double d;
00533         
00534         if(ch_tmp->GetMax() - ch_ptr->GetMax())
00535         {
00536           d = Findzero( param1, param2, ch_ptr->GetMax(), ch_tmp->GetMax());
00537           if( d <= (smin + kCarTolerance) ) smin = d * .99;
00538           if( d >= (smax - kCarTolerance) ) smax = d * .99 + .01;
00539         }
00540 
00541         if(ch_tmp->GetMin()-ch_ptr->GetMin())
00542         {
00543           d = Findzero( param1, param2, ch_ptr->GetMin(), ch_tmp->GetMin());
00544           if( d <= (smin + kCarTolerance) ) smin = d * .99;
00545           if( d >= (smax - kCarTolerance) ) smax = d * .99 + .01;
00546         }
00547         
00548         ch_tmp=ch_tmp->GetNextHull();
00549       }
00550 
00551       ch_ptr=ch_ptr->GetNextHull();
00552     }
00553     
00554     ch_tmp=ch_ptr;
00555     ch_ptr=ch_first;
00556         
00557     if (smin <= 0.0)  smin = 0.0;
00558     if (smax >= 1.0)  smax = 1.0;
00559     
00560     if ( (ch_ptr)
00561       && (Sign(ch_ptr->GetMin()) != Sign(ch_ptr->GetMax()))) smin = 0.0;
00562 
00563     if ( ch_tmp )
00564     {
00565       i = Sign(ch_tmp->GetMin()); // ch_tmp points to last nvex()_hull in List
00566       j = Sign(ch_tmp->GetMax());
00567       if ( (std::abs(i-j) > kCarTolerance)) smax = 1.0;
00568     }
00569   }
00570 
00571   ch_ptr=ch_first;
00572   while(ch_ptr && (ch_ptr!=ch_ptr->GetNextHull()))
00573   {
00574     ch_tmp=ch_ptr;
00575     ch_ptr=ch_ptr->GetNextHull();
00576     delete ch_tmp;
00577   }
00578 
00579   delete ch_ptr;
00580   
00581   // Testing...    
00582   Clips++; 
00583 }

void G4BezierSurface::Dir ( G4int  d  )  [inline]

Definition at line 62 of file G4BezierSurface.icc.

00063 {
00064   dir=d;
00065 }

G4int G4BezierSurface::GetOrder ( G4int  direction  )  const [inline]

Definition at line 86 of file G4BezierSurface.icc.

00087 {
00088   return order[direction];
00089 }

G4double G4BezierSurface::GetU (  )  const [inline]

Definition at line 98 of file G4BezierSurface.icc.

00099 {
00100   return (u_min + u_max)/2.0;
00101 }

G4double G4BezierSurface::GetV (  )  const [inline]

Definition at line 104 of file G4BezierSurface.icc.

00105 {
00106   return (v_min + v_max)/2.0;
00107 }

void G4BezierSurface::PutOrder ( G4int  direction,
G4int  value 
) [inline]

Definition at line 92 of file G4BezierSurface.icc.

00093 {
00094   order[direction]=value;
00095 }

void G4BezierSurface::SetAveragePoint ( G4Point3D  p  )  [inline]

Definition at line 44 of file G4BezierSurface.icc.

00045 {
00046   average_pt=p;
00047 }

G4double G4BezierSurface::SMax (  )  const [inline]

Definition at line 80 of file G4BezierSurface.icc.

00081 {
00082   return smax;
00083 }

G4double G4BezierSurface::SMin (  )  const [inline]

Definition at line 74 of file G4BezierSurface.icc.

00075 {
00076   return smin;
00077 }

G4Vector3D G4BezierSurface::SurfaceNormal ( const G4Point3D Pt  )  const [virtual]

Implements G4Surface.

Definition at line 91 of file G4BezierSurface.cc.

00092 {
00093   return G4Vector3D(0,0,0);
00094 }

G4double G4BezierSurface::UAverage (  )  const [inline]

Definition at line 50 of file G4BezierSurface.icc.

00051 {
00052   return average_u;
00053 }

G4double G4BezierSurface::VAverage (  )  const [inline]

Definition at line 56 of file G4BezierSurface.icc.

00057 {
00058   return average_v;
00059 }


Friends And Related Function Documentation

void CopySurface ( G4BezierSurface bez  )  [friend]

friend class G4BSplineSurface [friend]

Definition at line 53 of file G4BezierSurface.hh.

friend class G4ProjectedSurface [friend]

Definition at line 54 of file G4BezierSurface.hh.


Field Documentation

G4SurfaceList* G4BezierSurface::bezier_list [protected]

Definition at line 93 of file G4BezierSurface.hh.

Referenced by BIntersect(), and ClipBothDirs().

G4int G4BezierSurface::Clips = 0 [static, protected]

Definition at line 95 of file G4BezierSurface.hh.

Referenced by ClipSurface().

G4int G4BezierSurface::Splits = 0 [static, protected]

Definition at line 96 of file G4BezierSurface.hh.

G4double G4BezierSurface::Tolerance = 0 [static, protected]

Definition at line 97 of file G4BezierSurface.hh.

Referenced by BIntersect().


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:51:32 2013 for Geant4 by  doxygen 1.4.7