#include <G4BezierSurface.hh>
Inheritance diagram for G4BezierSurface:
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 | |
G4SurfaceList * | bezier_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) |
Definition at line 51 of file G4BezierSurface.hh.
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 }
G4Point3D G4BezierSurface::AveragePoint | ( | ) | const [inline] |
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] |
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] |
G4double G4BezierSurface::GetU | ( | ) | const [inline] |
G4double G4BezierSurface::GetV | ( | ) | const [inline] |
void G4BezierSurface::SetAveragePoint | ( | G4Point3D | p | ) | [inline] |
G4double G4BezierSurface::SMax | ( | ) | const [inline] |
G4double G4BezierSurface::SMin | ( | ) | const [inline] |
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] |
G4double G4BezierSurface::VAverage | ( | ) | const [inline] |
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.
G4SurfaceList* G4BezierSurface::bezier_list [protected] |
G4int G4BezierSurface::Clips = 0 [static, protected] |
G4int G4BezierSurface::Splits = 0 [static, protected] |
Definition at line 96 of file G4BezierSurface.hh.
G4double G4BezierSurface::Tolerance = 0 [static, protected] |