64 const std::vector<G4PhysicalVolumesSearchScene::Findings>& pvFindings,
65 G4int nDataPointsPerMaxHalfExtent,
67 G4int arrow3DLineSegmentsPerCircle)
68: fExtentForField(extentForField)
69, fPVFindings(pvFindings)
70, fNDataPointsPerMaxHalfExtent(nDataPointsPerMaxHalfExtent)
71, fRepresentation(representation)
72, fArrow3DLineSegmentsPerCircle(arrow3DLineSegmentsPerCircle)
73, fTypeOfField(typeOfField)
76 fType =
"G4"+typeOfField+
"FieldModel";
79 std::ostringstream oss;
80 oss <<
':' << fNDataPointsPerMaxHalfExtent
81 <<
':' << fArrow3DLineSegmentsPerCircle;
83 oss <<
" whole scene";
86 <<
':' << fExtentForField.
GetXmin()
87 <<
':' << fExtentForField.
GetXmax()
88 <<
':' << fExtentForField.
GetYmin()
89 <<
':' << fExtentForField.
GetYmax()
90 <<
':' << fExtentForField.
GetZmin()
91 <<
':' << fExtentForField.
GetZmax();
93 for (
const auto& findings: fPVFindings) {
95 <<
',' << findings.fpFoundPV->GetName()
96 <<
':' << findings.fFoundPVCopyNo;
101 oss <<
" light arrow";
120 const G4Field* globalField = 0;
121 const G4String intro =
"G4VFieldModel::DescribeYourselfTo: ";
122 if (globalFieldMgr) {
126 static G4bool warned =
false;
128 G4warn << intro <<
"Null global field pointer." <<
G4endl;
134 static G4bool warned =
false;
136 G4warn << intro <<
"No global field manager." <<
G4endl;
145 extent = fExtentForField;
153 const G4double xHalfScene = 0.5 * (xMax - xMin);
154 const G4double yHalfScene = 0.5 * (yMax - yMin);
155 const G4double zHalfScene = 0.5 * (zMax - zMin);
156 const G4double xSceneCentre = 0.5 * (xMax + xMin);
157 const G4double ySceneCentre = 0.5 * (yMax + yMin);
158 const G4double zSceneCentre = 0.5 * (zMax + zMin);
160 std::max(xHalfScene,std::max(yHalfScene,zHalfScene));
161 if (maxHalfScene <= 0.) {
167 const G4double interval = maxHalfScene / fNDataPointsPerMaxHalfExtent;
168 const G4int nDataPointsPerXHalfScene =
G4int(xHalfScene / interval);
169 const G4int nDataPointsPerYHalfScene =
G4int(yHalfScene / interval);
170 const G4int nDataPointsPerZHalfScene =
G4int(zHalfScene / interval);
171 const G4int nXSamples = 2 * nDataPointsPerXHalfScene + 1;
172 const G4int nYSamples = 2 * nDataPointsPerYHalfScene + 1;
173 const G4int nZSamples = 2 * nDataPointsPerZHalfScene + 1;
174 const G4int nSamples = nXSamples * nYSamples * nZSamples;
175 const G4double arrowLengthMax = 0.8 * interval;
178 std::vector<G4Point3D> Field(nSamples);
179 std::vector<G4Point3D> xyz(nSamples);
180 G4double FieldMagnitudeMax = -std::numeric_limits<G4double>::max();
183 for (
G4int i = 0; i < nXSamples; i++) {
184 G4double x = xSceneCentre + (i - nDataPointsPerXHalfScene) * interval;
186 for (
G4int j = 0; j < nYSamples; j++) {
187 G4double y = ySceneCentre + (j - nDataPointsPerYHalfScene) * interval;
189 for (
G4int k = 0; k < nZSamples; k++) {
190 G4double z = zSceneCentre + (k - nDataPointsPerZHalfScene) * interval;
193 const G4int ijk = i * nYSamples * nZSamples + j * nZSamples + k;
199 if (!fPVFindings.empty()) {
201 for (
const auto& findings: fPVFindings) {
203 G4int copyNo = findings.fFoundPVCopyNo;
208 solid = param->ComputeSolid(copyNo,pvParam);
212 const auto& transform = findings.fFoundObjectTransformation;
213 auto rotation = transform.getRotation();
214 auto translation = transform.getTranslation();
221 if (!isInPV)
continue;
228 const G4Field* field = globalField;
237 if (pRegionFieldMgr) {
257 if (mag > FieldMagnitudeMax) FieldMagnitudeMax = mag;
262 if (FieldMagnitudeMax <= 0.) {
263 G4warn <<
"No " << fTypeOfField <<
" field in this extent." <<
G4endl;
267 for (
G4int i = 0; i < nSamples; i++) {
268 const G4double Fmag = Field[i].mag();
269 const G4double f = Fmag / FieldMagnitudeMax;
270 if (f <= 0.)
continue;
272 G4double red = 0., green = 0., blue = 0., alpha = 1.;
275 red = 2. * (0.5 - f);
277 blue = 2. * (f - 0.5);
278 green = 2. * (1.0 - f);
280 const G4Colour arrowColour(red,green,blue,alpha);
283 G4bool drawAsLine =
false;
284 switch (fRepresentation) {
298 G4double arrowLength = arrowLengthMax * f;
300 if (f < 0.01) arrowLength = arrowLengthMax * 0.01;
301 const G4Point3D head = xyz[i] + arrowLength*Field[i]/Fmag;
308 FArrowLite.push_back(xyz[i]);
309 FArrowLite.push_back(head);
315 head.
x(), head.
y(), head.
z(),
316 arrowLength/5, arrowColour,
317 fArrowPrefix+
"Field",
318 fArrow3DLineSegmentsPerCircle);
Hep3Vector & transform(const HepRotation &)
void DescribeYourselfTo(G4VGraphicsScene &) override
const G4Field * GetDetectorField() const
G4bool DoesFieldExist() const
G4VSolid * GetSolid() const
G4Region * GetRegion() const
G4FieldManager * GetFieldManager() const
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
G4VPVParameterisation * GetParameterisation() const
G4FieldManager * GetFieldManager() const
static G4TransportationManager * GetTransportationManager()
G4Navigator * GetNavigatorForTracking() const
G4FieldManager * GetFieldManager() const
virtual void GetFieldAtLocation(const G4Field *field, const G4Point3D &position, G4double time, G4Point3D &result) const =0
virtual void DescribeYourselfTo(G4VGraphicsScene &sceneHandler)
G4VFieldModel(const G4String &typeOfField, const G4String &symbol="", const G4VisExtent &extentForField=G4VisExtent(), const std::vector< G4PhysicalVolumesSearchScene::Findings > &pvFindings=std::vector< G4PhysicalVolumesSearchScene::Findings >(), G4int nDataPointsPerHalfScene=10, Representation representation=Representation::fullArrow, G4int arrow3DLineSegmentsPerCircle=6)
virtual void BeginPrimitives(const G4Transform3D &objectTransformation=G4Transform3D())=0
virtual void AddPrimitive(const G4Polyline &)=0
virtual const G4VisExtent & GetExtent() const
virtual void EndPrimitives()=0
G4String fGlobalDescription
G4LogicalVolume * GetLogicalVolume() const
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
void SetLineWidth(G4double)
static const G4VisExtent & GetNullExtent()
void SetVisAttributes(const G4VisAttributes *)