Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // Implementation for G4ReflectedSolid class << 26 // >> 27 // $Id: G4ReflectedSolid.cc,v 1.11 2006/11/08 09:56:33 gcosmo Exp $ >> 28 // >> 29 // GEANT4 tag $Name: geant4-09-02-patch-03 $ >> 30 // >> 31 // Implementation for G4ReflectedSolid class for boolean >> 32 // operations between other solids 27 // 33 // 28 // Author: Vladimir Grichine, 23.07.01 (Vladi 34 // Author: Vladimir Grichine, 23.07.01 (Vladimir.Grichine@cern.ch) >> 35 // 29 // ------------------------------------------- 36 // -------------------------------------------------------------------- 30 37 31 #include "G4ReflectedSolid.hh" 38 #include "G4ReflectedSolid.hh" 32 39 33 #include <sstream> 40 #include <sstream> 34 41 35 #include "G4Point3D.hh" 42 #include "G4Point3D.hh" 36 #include "G4Vector3D.hh" << 43 #include "G4Normal3D.hh" 37 44 38 #include "G4AffineTransform.hh" << 39 #include "G4Transform3D.hh" << 40 #include "G4VoxelLimits.hh" 45 #include "G4VoxelLimits.hh" 41 46 42 #include "G4VPVParameterisation.hh" 47 #include "G4VPVParameterisation.hh" 43 48 44 #include "G4VGraphicsScene.hh" 49 #include "G4VGraphicsScene.hh" 45 #include "G4Polyhedron.hh" 50 #include "G4Polyhedron.hh" >> 51 #include "G4NURBS.hh" >> 52 // #include "G4NURBSbox.hh" >> 53 46 54 47 ////////////////////////////////////////////// 55 ///////////////////////////////////////////////////////////////// 48 // 56 // 49 // Constructor using HepTransform3D, in fact H 57 // Constructor using HepTransform3D, in fact HepReflect3D 50 58 51 G4ReflectedSolid::G4ReflectedSolid( const G4St 59 G4ReflectedSolid::G4ReflectedSolid( const G4String& pName, 52 G4VS 60 G4VSolid* pSolid , 53 const G4Tr << 61 const G4Transform3D& transform ) 54 : G4VSolid(pName) << 62 : G4VSolid(pName), fpPolyhedron(0) 55 { 63 { 56 fPtrSolid = pSolid; << 64 fPtrSolid = pSolid ; 57 fDirectTransform3D = new G4Transform3D(trans << 65 G4RotationMatrix rotMatrix ; 58 } << 66 59 << 67 fDirectTransform = 60 ////////////////////////////////////////////// << 68 new G4AffineTransform(rotMatrix, transform.getTranslation()) ; 61 // << 69 fPtrTransform = 62 << 70 new G4AffineTransform(rotMatrix, transform.getTranslation()) ; 63 G4ReflectedSolid::~G4ReflectedSolid() << 71 fPtrTransform->Invert() ; 64 { << 65 delete fDirectTransform3D; fDirectTransform3 << 66 delete fpPolyhedron; fpPolyhedron = nullptr; << 67 } << 68 << 69 ////////////////////////////////////////////// << 70 // << 71 72 72 G4ReflectedSolid::G4ReflectedSolid(const G4Ref << 73 fDirectTransform3D = new G4Transform3D(transform) ; 73 : G4VSolid(rhs), fPtrSolid(rhs.fPtrSolid) << 74 fPtrTransform3D = new G4Transform3D(transform.inverse()) ; 74 { << 75 fDirectTransform3D = new G4Transform3D(*rhs. << 76 } 75 } 77 76 78 ////////////////////////////////////////////// 77 /////////////////////////////////////////////////////////////////// 79 // 78 // 80 79 81 G4ReflectedSolid& G4ReflectedSolid::operator=( << 80 G4ReflectedSolid::~G4ReflectedSolid() 82 { 81 { 83 // Check assignment to self << 82 if(fPtrTransform) 84 // << 83 { 85 if (this == &rhs) { return *this; } << 84 delete fPtrTransform; fPtrTransform=0; 86 << 85 delete fDirectTransform; fDirectTransform=0; 87 // Copy base class data << 86 } 88 // << 87 if(fPtrTransform3D) 89 G4VSolid::operator=(rhs); << 88 { 90 << 89 delete fPtrTransform3D; fPtrTransform3D=0; 91 // Copy data << 90 delete fDirectTransform3D; fDirectTransform3D=0; 92 // << 91 } 93 fPtrSolid = rhs.fPtrSolid; << 92 delete fpPolyhedron; 94 delete fDirectTransform3D; << 95 fDirectTransform3D = new G4Transform3D(*rhs. << 96 fRebuildPolyhedron = false; << 97 delete fpPolyhedron; fpPolyhedron = nullptr; << 98 << 99 return *this; << 100 } 93 } 101 94 102 ////////////////////////////////////////////// << 103 // << 104 << 105 G4GeometryType G4ReflectedSolid::GetEntityType 95 G4GeometryType G4ReflectedSolid::GetEntityType() const 106 { 96 { 107 return {"G4ReflectedSolid"}; << 97 return G4String("G4ReflectedSolid"); 108 } 98 } 109 99 110 const G4ReflectedSolid* G4ReflectedSolid::GetR 100 const G4ReflectedSolid* G4ReflectedSolid::GetReflectedSolidPtr() const 111 { 101 { 112 return this; 102 return this; 113 } 103 } 114 104 115 G4ReflectedSolid* G4ReflectedSolid::GetReflect 105 G4ReflectedSolid* G4ReflectedSolid::GetReflectedSolidPtr() 116 { 106 { 117 return this; 107 return this; 118 } 108 } 119 109 120 G4VSolid* G4ReflectedSolid::GetConstituentMove 110 G4VSolid* G4ReflectedSolid::GetConstituentMovedSolid() const 121 { 111 { 122 return fPtrSolid; 112 return fPtrSolid; 123 } 113 } 124 114 125 ////////////////////////////////////////////// 115 ///////////////////////////////////////////////////////////////////////////// 126 // << 116 >> 117 G4AffineTransform G4ReflectedSolid::GetTransform() const >> 118 { >> 119 G4AffineTransform aTransform = *fPtrTransform; >> 120 return aTransform; >> 121 } >> 122 >> 123 void G4ReflectedSolid::SetTransform(G4AffineTransform& transform) >> 124 { >> 125 fPtrTransform = &transform ; >> 126 fpPolyhedron = 0; >> 127 } >> 128 >> 129 ////////////////////////////////////////////////////////////////////////////// >> 130 >> 131 G4AffineTransform G4ReflectedSolid::GetDirectTransform() const >> 132 { >> 133 G4AffineTransform aTransform= *fDirectTransform; >> 134 return aTransform; >> 135 } >> 136 >> 137 void G4ReflectedSolid::SetDirectTransform(G4AffineTransform& transform) >> 138 { >> 139 fDirectTransform = &transform ; >> 140 fpPolyhedron = 0; >> 141 } >> 142 >> 143 ///////////////////////////////////////////////////////////////////////////// 127 144 128 G4Transform3D G4ReflectedSolid::GetTransform3 145 G4Transform3D G4ReflectedSolid::GetTransform3D() const 129 { 146 { 130 return fDirectTransform3D->inverse(); << 147 G4Transform3D aTransform = *fPtrTransform3D; >> 148 return aTransform; >> 149 } >> 150 >> 151 void G4ReflectedSolid::SetTransform3D(G4Transform3D& transform) >> 152 { >> 153 fPtrTransform3D = &transform ; >> 154 fpPolyhedron = 0; 131 } 155 } 132 156 >> 157 ////////////////////////////////////////////////////////////////////////////// >> 158 133 G4Transform3D G4ReflectedSolid::GetDirectTran 159 G4Transform3D G4ReflectedSolid::GetDirectTransform3D() const 134 { 160 { 135 G4Transform3D aTransform = *fDirectTransform << 161 G4Transform3D aTransform= *fDirectTransform3D; 136 return aTransform; 162 return aTransform; 137 } 163 } 138 164 139 void G4ReflectedSolid::SetDirectTransform3D(G4 165 void G4ReflectedSolid::SetDirectTransform3D(G4Transform3D& transform) 140 { 166 { 141 fDirectTransform3D = &transform; << 167 fDirectTransform3D = &transform ; 142 fRebuildPolyhedron = true; << 168 fpPolyhedron = 0; 143 } 169 } 144 170 145 ////////////////////////////////////////////// << 171 ///////////////////////////////////////////////////////////////////////////// 146 // << 147 // Get bounding box << 148 172 149 void G4ReflectedSolid::BoundingLimits(G4ThreeV << 173 G4RotationMatrix G4ReflectedSolid::GetFrameRotation() const 150 G4ThreeV << 151 { 174 { 152 fPtrSolid->BoundingLimits(pMin,pMax); << 175 G4RotationMatrix InvRotation= fDirectTransform->NetRotation(); 153 G4double xmin = pMin.x(), ymin = pMin.y(), z << 176 return InvRotation; 154 G4double xmax = pMax.x(), ymax = pMax.y(), z << 177 } 155 G4double xx = fDirectTransform3D->xx(); << 156 G4double yy = fDirectTransform3D->yy(); << 157 G4double zz = fDirectTransform3D->zz(); << 158 178 159 if (std::abs(xx) == 1 && std::abs(yy) == 1 & << 179 void G4ReflectedSolid::SetFrameRotation(const G4RotationMatrix& matrix) 160 { << 180 { 161 // Special case of reflection in axis and << 181 fDirectTransform->SetNetRotation(matrix); 162 // << 182 } 163 if (xx == -1) { G4double tmp = -xmin; xmin << 164 if (yy == -1) { G4double tmp = -ymin; ymin << 165 if (zz == -1) { G4double tmp = -zmin; zmin << 166 xmin += fDirectTransform3D->dx(); << 167 xmax += fDirectTransform3D->dx(); << 168 ymin += fDirectTransform3D->dy(); << 169 ymax += fDirectTransform3D->dy(); << 170 zmin += fDirectTransform3D->dz(); << 171 zmax += fDirectTransform3D->dz(); << 172 } << 173 else << 174 { << 175 // Use additional reflection in Z to set u << 176 // << 177 G4Transform3D transform3D = G4ReflectZ3D() << 178 G4AffineTransform transform(transform3D.ge << 179 transform3D.ge << 180 << 181 // Find bounding box << 182 // << 183 G4VoxelLimits unLimit; << 184 fPtrSolid->CalculateExtent(kXAxis,unLimit, << 185 fPtrSolid->CalculateExtent(kYAxis,unLimit, << 186 fPtrSolid->CalculateExtent(kZAxis,unLimit, << 187 } << 188 183 189 pMin.set(xmin,ymin,-zmax); << 184 ///////////////////////////////////////////////////////////////////////////// 190 pMax.set(xmax,ymax,-zmin); << 191 185 192 // Check correctness of the bounding box << 186 G4ThreeVector G4ReflectedSolid::GetFrameTranslation() const 193 // << 187 { 194 if (pMin.x() >= pMax.x() || pMin.y() >= pMax << 188 return fPtrTransform->NetTranslation(); 195 { << 196 std::ostringstream message; << 197 message << "Bad bounding box (min >= max) << 198 << GetName() << " !" << 199 << "\npMin = " << pMin << 200 << "\npMax = " << pMax; << 201 G4Exception("G4ReflectedSolid::BoundingLim << 202 JustWarning, message); << 203 DumpInfo(); << 204 } << 205 } 189 } 206 190 207 ////////////////////////////////////////////// << 191 void G4ReflectedSolid::SetFrameTranslation(const G4ThreeVector& vector) 208 // << 192 { 209 // Calculate extent under transform and specif << 193 fPtrTransform->SetNetTranslation(vector); >> 194 } >> 195 >> 196 /////////////////////////////////////////////////////////////// 210 197 >> 198 G4RotationMatrix G4ReflectedSolid::GetObjectRotation() const >> 199 { >> 200 G4RotationMatrix Rotation= fPtrTransform->NetRotation(); >> 201 return Rotation; >> 202 } >> 203 >> 204 void G4ReflectedSolid::SetObjectRotation(const G4RotationMatrix& matrix) >> 205 { >> 206 fPtrTransform->SetNetRotation(matrix); >> 207 } >> 208 >> 209 /////////////////////////////////////////////////////////////////////// >> 210 >> 211 G4ThreeVector G4ReflectedSolid::GetObjectTranslation() const >> 212 { >> 213 return fDirectTransform->NetTranslation(); >> 214 } >> 215 >> 216 void G4ReflectedSolid::SetObjectTranslation(const G4ThreeVector& vector) >> 217 { >> 218 fDirectTransform->SetNetTranslation(vector); >> 219 } >> 220 >> 221 /////////////////////////////////////////////////////////////// >> 222 // >> 223 // >> 224 211 G4bool 225 G4bool 212 G4ReflectedSolid::CalculateExtent( const EAxis 226 G4ReflectedSolid::CalculateExtent( const EAxis pAxis, 213 const G4Vox << 227 const G4VoxelLimits& pVoxelLimit, 214 const G4Aff 228 const G4AffineTransform& pTransform, 215 G4dou 229 G4double& pMin, 216 G4dou << 230 G4double& pMax ) const 217 { 231 { 218 // Separation of transformations. Calculatio << 232 219 // in a reflection of the global space. In s << 233 G4VoxelLimits unLimit; 220 // reflected, but the solid is transformed j << 234 G4AffineTransform unTransform; 221 // It allows one to use CalculateExtent() of << 235 222 << 236 G4double x1 = -kInfinity, x2 = kInfinity, 223 // Reflect voxel limits in Z << 237 y1 = -kInfinity, y2 = kInfinity, 224 // << 238 z1 = -kInfinity, z2 = kInfinity; 225 G4VoxelLimits limits; << 239 226 limits.AddLimit(kXAxis, pVoxelLimits.GetMinX << 240 G4bool existsAfterClip = false ; 227 pVoxelLimits.GetMaxX << 241 existsAfterClip = 228 limits.AddLimit(kYAxis, pVoxelLimits.GetMinY << 242 fPtrSolid->CalculateExtent(kXAxis,unLimit,unTransform,x1,x2); 229 pVoxelLimits.GetMaxY << 243 existsAfterClip = 230 limits.AddLimit(kZAxis,-pVoxelLimits.GetMaxZ << 244 fPtrSolid->CalculateExtent(kYAxis,unLimit,unTransform,y1,y2); 231 -pVoxelLimits.GetMinZ << 245 existsAfterClip = 232 << 246 fPtrSolid->CalculateExtent(kZAxis,unLimit,unTransform,z1,z2); 233 // Set affine transformation << 247 234 // << 248 existsAfterClip = false; 235 G4Transform3D transform3D = G4ReflectZ3D()*p << 249 pMin = +kInfinity ; 236 G4AffineTransform transform(transform3D.getR << 250 pMax = -kInfinity ; 237 transform3D.getT << 251 238 << 252 G4Transform3D pTransform3D = G4Transform3D(pTransform.NetRotation().inverse(), 239 // Find extent << 253 pTransform.NetTranslation()); 240 // << 254 241 if (!fPtrSolid->CalculateExtent(pAxis, limit << 255 G4Transform3D transform3D = pTransform3D*(*fDirectTransform3D); >> 256 >> 257 G4Point3D tmpPoint; >> 258 >> 259 // Calculate rotated vertex coordinates >> 260 >> 261 G4ThreeVectorList* vertices = new G4ThreeVectorList(); >> 262 vertices->reserve(8); >> 263 >> 264 if (vertices) 242 { 265 { 243 return false; << 266 G4ThreeVector vertex0(x1,y1,z1) ; >> 267 tmpPoint = transform3D*G4Point3D(vertex0); >> 268 vertex0 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 269 vertices->push_back(vertex0); >> 270 >> 271 G4ThreeVector vertex1(x2,y1,z1) ; >> 272 tmpPoint = transform3D*G4Point3D(vertex1); >> 273 vertex1 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 274 vertices->push_back(vertex1); >> 275 >> 276 G4ThreeVector vertex2(x2,y2,z1) ; >> 277 tmpPoint = transform3D*G4Point3D(vertex2); >> 278 vertex2 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 279 vertices->push_back(vertex2); >> 280 >> 281 G4ThreeVector vertex3(x1,y2,z1) ; >> 282 tmpPoint = transform3D*G4Point3D(vertex3); >> 283 vertex3 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 284 vertices->push_back(vertex3); >> 285 >> 286 G4ThreeVector vertex4(x1,y1,z2) ; >> 287 tmpPoint = transform3D*G4Point3D(vertex4); >> 288 vertex4 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 289 vertices->push_back(vertex4); >> 290 >> 291 G4ThreeVector vertex5(x2,y1,z2) ; >> 292 tmpPoint = transform3D*G4Point3D(vertex5); >> 293 vertex5 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 294 vertices->push_back(vertex5); >> 295 >> 296 G4ThreeVector vertex6(x2,y2,z2) ; >> 297 tmpPoint = transform3D*G4Point3D(vertex6); >> 298 vertex6 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 299 vertices->push_back(vertex6); >> 300 >> 301 G4ThreeVector vertex7(x1,y2,z2) ; >> 302 tmpPoint = transform3D*G4Point3D(vertex7); >> 303 vertex7 = G4ThreeVector(tmpPoint.x(),tmpPoint.y(),tmpPoint.z()); >> 304 vertices->push_back(vertex7); 244 } 305 } 245 if (pAxis == kZAxis) << 306 else 246 { 307 { 247 G4double tmp= -pMin; pMin= -pMax; pMax= tm << 308 DumpInfo(); >> 309 G4Exception("G4ReflectedSolid::CalculateExtent()", >> 310 "FatalError", FatalException, >> 311 "Error in allocation of vertices. Out of memory !"); 248 } 312 } >> 313 >> 314 ClipCrossSection(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ; >> 315 ClipCrossSection(vertices,4,pVoxelLimit,pAxis,pMin,pMax) ; >> 316 ClipBetweenSections(vertices,0,pVoxelLimit,pAxis,pMin,pMax) ; >> 317 >> 318 if (pVoxelLimit.IsLimited(pAxis) == false) >> 319 { >> 320 if ( pMin != kInfinity || pMax != -kInfinity ) >> 321 { >> 322 existsAfterClip = true ; >> 323 >> 324 // Add 2*tolerance to avoid precision troubles >> 325 >> 326 pMin -= kCarTolerance; >> 327 pMax += kCarTolerance; >> 328 } >> 329 } >> 330 else >> 331 { >> 332 G4ThreeVector clipCentre( >> 333 ( pVoxelLimit.GetMinXExtent()+pVoxelLimit.GetMaxXExtent())*0.5, >> 334 ( pVoxelLimit.GetMinYExtent()+pVoxelLimit.GetMaxYExtent())*0.5, >> 335 ( pVoxelLimit.GetMinZExtent()+pVoxelLimit.GetMaxZExtent())*0.5); >> 336 >> 337 if ( pMin != kInfinity || pMax != -kInfinity ) >> 338 { >> 339 existsAfterClip = true ; >> 340 249 341 250 return true; << 342 // Check to see if endpoints are in the solid 251 } << 252 343 253 ////////////////////////////////////////////// << 344 clipCentre(pAxis) = pVoxelLimit.GetMinExtent(pAxis); >> 345 >> 346 if (Inside(transform3D.inverse()*G4Point3D(clipCentre)) != kOutside) >> 347 { >> 348 pMin = pVoxelLimit.GetMinExtent(pAxis); >> 349 } >> 350 else >> 351 { >> 352 pMin -= kCarTolerance; >> 353 } >> 354 clipCentre(pAxis) = pVoxelLimit.GetMaxExtent(pAxis); >> 355 >> 356 if (Inside(transform3D.inverse()*G4Point3D(clipCentre)) != kOutside) >> 357 { >> 358 pMax = pVoxelLimit.GetMaxExtent(pAxis); >> 359 } >> 360 else >> 361 { >> 362 pMax += kCarTolerance; >> 363 } >> 364 } >> 365 // Check for case where completely enveloping clipping volume >> 366 // If point inside then we are confident that the solid completely >> 367 // envelopes the clipping volume. Hence set min/max extents according >> 368 // to clipping volume extents along the specified axis. >> 369 >> 370 else if (Inside(transform3D.inverse()*G4Point3D(clipCentre)) != kOutside) >> 371 { >> 372 existsAfterClip = true ; >> 373 pMin = pVoxelLimit.GetMinExtent(pAxis) ; >> 374 pMax = pVoxelLimit.GetMaxExtent(pAxis) ; >> 375 } >> 376 } >> 377 delete vertices; >> 378 return existsAfterClip; >> 379 } >> 380 >> 381 ///////////////////////////////////////////////////// 254 // 382 // 255 // 383 // 256 384 257 EInside G4ReflectedSolid::Inside(const G4Three << 385 EInside G4ReflectedSolid::Inside(const G4ThreeVector& p) const 258 { 386 { 259 G4ThreeVector newPoint = (*fDirectTransform3 << 387 260 return fPtrSolid->Inside(newPoint); << 388 G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ; >> 389 // G4Point3D newPoint = (*fPtrTransform3D)*G4Point3D(p) ; >> 390 >> 391 return fPtrSolid->Inside(G4ThreeVector(newPoint.x(), >> 392 newPoint.y(), >> 393 newPoint.z())) ; 261 } 394 } 262 395 263 ////////////////////////////////////////////// 396 ////////////////////////////////////////////////////////////// 264 // 397 // 265 // 398 // 266 399 267 G4ThreeVector 400 G4ThreeVector 268 G4ReflectedSolid::SurfaceNormal( const G4Three 401 G4ReflectedSolid::SurfaceNormal( const G4ThreeVector& p ) const 269 { 402 { 270 G4ThreeVector newPoint = (*fDirectTransform3 << 403 G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ; 271 G4Vector3D normal = fPtrSolid->SurfaceNormal << 404 G4ThreeVector normal = 272 return (*fDirectTransform3D)*normal; << 405 fPtrSolid->SurfaceNormal(G4ThreeVector(newPoint.x(), >> 406 newPoint.y(), >> 407 newPoint.z() ) ) ; >> 408 G4Point3D newN = (*fDirectTransform3D)*G4Point3D(normal) ; >> 409 newN.unit() ; >> 410 >> 411 return G4ThreeVector(newN.x(),newN.y(),newN.z()) ; 273 } 412 } 274 413 275 ////////////////////////////////////////////// 414 ///////////////////////////////////////////////////////////// 276 // 415 // 277 // The same algorithm as in DistanceToIn(p) 416 // The same algorithm as in DistanceToIn(p) 278 417 279 G4double 418 G4double 280 G4ReflectedSolid::DistanceToIn( const G4ThreeV 419 G4ReflectedSolid::DistanceToIn( const G4ThreeVector& p, 281 const G4ThreeV << 420 const G4ThreeVector& v ) const 282 { 421 { 283 G4ThreeVector newPoint = (*fDirectTransf << 422 G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ; 284 G4ThreeVector newDirection = (*fDirectTransf << 423 G4Point3D newDirection = (*fDirectTransform3D)*G4Point3D(v) ; 285 return fPtrSolid->DistanceToIn(newPoint,newD << 424 newDirection.unit() ; >> 425 return fPtrSolid->DistanceToIn( >> 426 G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z()), >> 427 G4ThreeVector(newDirection.x(),newDirection.y(),newDirection.z())) ; 286 } 428 } 287 429 288 ////////////////////////////////////////////// 430 //////////////////////////////////////////////////////// 289 // 431 // 290 // Approximate nearest distance from the point 432 // Approximate nearest distance from the point p to the intersection of 291 // two solids 433 // two solids 292 434 293 G4double 435 G4double 294 G4ReflectedSolid::DistanceToIn( const G4ThreeV << 436 G4ReflectedSolid::DistanceToIn( const G4ThreeVector& p) const 295 { 437 { 296 G4ThreeVector newPoint = (*fDirectTransform3 << 438 G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ; 297 return fPtrSolid->DistanceToIn(newPoint); << 439 return fPtrSolid->DistanceToIn( >> 440 G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z())) ; 298 } 441 } 299 442 300 ////////////////////////////////////////////// 443 ////////////////////////////////////////////////////////// 301 // 444 // 302 // The same algorithm as DistanceToOut(p) 445 // The same algorithm as DistanceToOut(p) 303 446 304 G4double 447 G4double 305 G4ReflectedSolid::DistanceToOut( const G4Three 448 G4ReflectedSolid::DistanceToOut( const G4ThreeVector& p, 306 const G4Three 449 const G4ThreeVector& v, 307 const G4bool 450 const G4bool calcNorm, 308 G4bool* << 451 G4bool *validNorm, 309 G4Three << 452 G4ThreeVector *n ) const 310 { 453 { 311 G4ThreeVector solNorm; << 454 G4ThreeVector solNorm ; 312 << 313 G4ThreeVector newPoint = (*fDirectTransf << 314 G4ThreeVector newDirection = (*fDirectTransf << 315 455 316 G4double dist = fPtrSolid->DistanceToOut(new << 456 G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p) ; 317 cal << 457 G4Point3D newDirection = (*fDirectTransform3D)*G4Point3D(v); >> 458 newDirection.unit() ; >> 459 >> 460 G4double dist = >> 461 fPtrSolid->DistanceToOut( >> 462 G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z()), >> 463 G4ThreeVector(newDirection.x(),newDirection.y(),newDirection.z()), >> 464 calcNorm, validNorm, &solNorm) ; 318 if(calcNorm) 465 if(calcNorm) 319 { 466 { 320 *n = (*fDirectTransform3D)*G4Vector3D(solN << 467 G4Point3D newN = (*fDirectTransform3D)*G4Point3D(solNorm); >> 468 newN.unit() ; >> 469 *n = G4ThreeVector(newN.x(),newN.y(),newN.z()); 321 } 470 } 322 return dist; << 471 return dist ; 323 } 472 } 324 473 325 ////////////////////////////////////////////// 474 ////////////////////////////////////////////////////////////// 326 // 475 // 327 // Inverted algorithm of DistanceToIn(p) 476 // Inverted algorithm of DistanceToIn(p) 328 477 329 G4double 478 G4double 330 G4ReflectedSolid::DistanceToOut( const G4Three 479 G4ReflectedSolid::DistanceToOut( const G4ThreeVector& p ) const 331 { 480 { 332 G4ThreeVector newPoint = (*fDirectTransform3 << 481 G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p); 333 return fPtrSolid->DistanceToOut(newPoint); << 482 return fPtrSolid->DistanceToOut( >> 483 G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z())); 334 } 484 } 335 485 336 ////////////////////////////////////////////// 486 ////////////////////////////////////////////////////////////// 337 // 487 // 338 // 488 // 339 489 340 void 490 void 341 G4ReflectedSolid::ComputeDimensions( G4V 491 G4ReflectedSolid::ComputeDimensions( G4VPVParameterisation*, 342 const G4i 492 const G4int, 343 const G4V 493 const G4VPhysicalVolume* ) 344 { 494 { 345 DumpInfo(); 495 DumpInfo(); 346 G4Exception("G4ReflectedSolid::ComputeDimens << 496 G4Exception("G4BooleanSolid::ComputeDimensions()", 347 "GeomMgt0001", FatalException, << 497 "NotApplicable", FatalException, 348 "Method not applicable in this 498 "Method not applicable in this context!"); 349 } 499 } 350 500 351 ////////////////////////////////////////////// 501 ////////////////////////////////////////////////////////////// 352 // 502 // 353 // Return volume << 354 << 355 G4double G4ReflectedSolid::GetCubicVolume() << 356 { << 357 return fPtrSolid->GetCubicVolume(); << 358 } << 359 << 360 ////////////////////////////////////////////// << 361 // << 362 // Return surface area << 363 << 364 G4double G4ReflectedSolid::GetSurfaceArea() << 365 { << 366 return fPtrSolid->GetSurfaceArea(); << 367 } << 368 << 369 ////////////////////////////////////////////// << 370 // << 371 // Return a point (G4ThreeVector) randomly and 503 // Return a point (G4ThreeVector) randomly and uniformly selected 372 // on the solid surface 504 // on the solid surface 373 505 374 G4ThreeVector G4ReflectedSolid::GetPointOnSurf 506 G4ThreeVector G4ReflectedSolid::GetPointOnSurface() const 375 { 507 { 376 G4ThreeVector p = fPtrSolid->GetPointOnSur << 508 G4ThreeVector p = fPtrSolid->GetPointOnSurface(); 377 return (*fDirectTransform3D)*G4Point3D(p); << 509 G4Point3D newPoint = (*fDirectTransform3D)*G4Point3D(p); 378 } << 379 << 380 ////////////////////////////////////////////// << 381 // << 382 // Return the number of constituents used for << 383 // of the solid << 384 << 385 G4int G4ReflectedSolid::GetNumOfConstituents() << 386 { << 387 return fPtrSolid->GetNumOfConstituents(); << 388 } << 389 << 390 ////////////////////////////////////////////// << 391 // << 392 // Return true if the reflected solid has only << 393 << 394 G4bool G4ReflectedSolid::IsFaceted() const << 395 { << 396 return fPtrSolid->IsFaceted(); << 397 } << 398 << 399 ////////////////////////////////////////////// << 400 // << 401 // Make a clone of this object << 402 510 403 G4VSolid* G4ReflectedSolid::Clone() const << 511 return G4ThreeVector(newPoint.x(),newPoint.y(),newPoint.z()); 404 { << 405 return new G4ReflectedSolid(*this); << 406 } 512 } 407 513 408 ////////////////////////////////////////////// 514 ////////////////////////////////////////////////////////////////////////// 409 // 515 // 410 // Stream object contents to an output stream 516 // Stream object contents to an output stream 411 517 412 std::ostream& G4ReflectedSolid::StreamInfo(std 518 std::ostream& G4ReflectedSolid::StreamInfo(std::ostream& os) const 413 { 519 { 414 os << "------------------------------------- 520 os << "-----------------------------------------------------------\n" 415 << " *** Dump for Reflected solid - " 521 << " *** Dump for Reflected solid - " << GetName() << " ***\n" 416 << " ================================= 522 << " ===================================================\n" 417 << " Solid type: " << GetEntityType() << 523 << " Solid type: " << GetEntityType() << "\n" 418 << " Parameters of constituent solid: \n" 524 << " Parameters of constituent solid: \n" 419 << "===================================== 525 << "===========================================================\n"; 420 fPtrSolid->StreamInfo(os); 526 fPtrSolid->StreamInfo(os); 421 os << "===================================== 527 os << "===========================================================\n" 422 << " Transformations: \n" 528 << " Transformations: \n" 423 << " Direct transformation - translati 529 << " Direct transformation - translation : \n" 424 << " " << fDirectTransform3D->g << 530 << " " << fDirectTransform->NetTranslation() << "\n" 425 << " - rotation 531 << " - rotation : \n" 426 << " "; 532 << " "; 427 fDirectTransform3D->getRotation().print(os); << 533 fDirectTransform->NetRotation().print(os); 428 os << "\n" 534 os << "\n" 429 << "===================================== 535 << "===========================================================\n"; 430 536 431 return os; 537 return os; 432 } 538 } 433 539 434 ////////////////////////////////////////////// 540 ///////////////////////////////////////////////// 435 // 541 // 436 // 542 // 437 543 438 void 544 void 439 G4ReflectedSolid::DescribeYourselfTo ( G4VGrap 545 G4ReflectedSolid::DescribeYourselfTo ( G4VGraphicsScene& scene ) const 440 { 546 { 441 scene.AddSolid (*this); 547 scene.AddSolid (*this); 442 } 548 } 443 549 444 ////////////////////////////////////////////// 550 //////////////////////////////////////////////////// 445 // 551 // 446 // 552 // 447 553 448 G4Polyhedron* 554 G4Polyhedron* 449 G4ReflectedSolid::CreatePolyhedron () const 555 G4ReflectedSolid::CreatePolyhedron () const 450 { 556 { 451 G4Polyhedron* polyhedron = fPtrSolid->Create 557 G4Polyhedron* polyhedron = fPtrSolid->CreatePolyhedron(); 452 if (polyhedron != nullptr) << 558 if (polyhedron) 453 { 559 { 454 polyhedron->Transform(*fDirectTransform3D) 560 polyhedron->Transform(*fDirectTransform3D); 455 return polyhedron; 561 return polyhedron; 456 } 562 } 457 else 563 else 458 { 564 { 459 std::ostringstream message; << 565 std::ostringstream oss; 460 message << "Solid - " << GetName() << 566 oss << "Solid - " << GetName() 461 << " - original solid has no" << G << 567 << " - original solid has no" << G4endl 462 << "corresponding polyhedron. Retu << 568 << " corresponding polyhedron. Returning NULL!"; 463 G4Exception("G4ReflectedSolid::CreatePolyh << 569 G4Exception("G4ReflectedSolid::CreatePolyhedron()", "InvalidSetup", 464 "GeomMgt1001", JustWarning, me << 570 JustWarning, oss.str().c_str()); 465 return nullptr; << 571 return 0; 466 } 572 } 467 } 573 } 468 574 469 ////////////////////////////////////////////// 575 ///////////////////////////////////////////////////////// 470 // 576 // 471 // 577 // 472 578 >> 579 G4NURBS* >> 580 G4ReflectedSolid::CreateNURBS () const >> 581 { >> 582 // Take into account local transformation - see CreatePolyhedron. >> 583 // return fPtrSolid->CreateNURBS() ; >> 584 return 0; >> 585 } >> 586 >> 587 ///////////////////////////////////////////////////////// >> 588 // >> 589 // >> 590 473 G4Polyhedron* 591 G4Polyhedron* 474 G4ReflectedSolid::GetPolyhedron () const 592 G4ReflectedSolid::GetPolyhedron () const 475 { 593 { 476 if ((fpPolyhedron == nullptr) || fRebuildPol << 594 if (!fpPolyhedron || 477 (fpPolyhedron->GetNumberOfRotationStepsA << 595 fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() != 478 fpPolyhedron->GetNumberOfRotationSteps( << 596 fpPolyhedron->GetNumberOfRotationSteps()) 479 { 597 { 480 fpPolyhedron = CreatePolyhedron(); << 598 delete fpPolyhedron; 481 fRebuildPolyhedron = false; << 599 fpPolyhedron = CreatePolyhedron (); 482 } 600 } 483 return fpPolyhedron; 601 return fpPolyhedron; 484 } 602 } 485 603