File indexing completed on 2026-03-30 07:51:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "PerspectiveVisAction.hh"
0030
0031 #include "PerspectiveVisActionMessenger.hh"
0032
0033 #include "G4Box.hh"
0034 #include "G4Point3D.hh"
0035 #include "G4Polyhedron.hh"
0036 #include "G4Polyline.hh"
0037 #include "G4SystemOfUnits.hh"
0038 #include "G4VVisManager.hh"
0039 #include "G4Vector3D.hh"
0040 #include "G4VisAttributes.hh"
0041
0042
0043
0044 PerspectiveVisAction::PerspectiveVisAction()
0045 : G4VUserVisAction(),
0046 fpVisManager(0),
0047 fOptionString("none"),
0048 fScene("room-and-chair"),
0049 fRoomX(2.5 * m),
0050 fRoomY(2.5 * m),
0051 fRoomZ(1.3 * m),
0052 fWindowX(10 * cm),
0053 fWindowY(75 * cm),
0054 fWindowZ(50 * cm),
0055 fWindowSillHeight(80 * cm),
0056 fWindowOffset(-50 * cm),
0057 fDoorFrameX(10 * cm),
0058 fDoorFrameY(50 * cm),
0059 fDoorFrameZ(1 * m),
0060 fDoorFrameOffset(1.5 * m),
0061 fDoorX(2 * cm),
0062 fDoorY(50 * cm),
0063 fDoorZ(1 * m),
0064 fChairX(20 * cm),
0065 fChairY(20 * cm),
0066 fChairZ(45 * cm),
0067 fChairSeat(20 * cm),
0068 fChairThickness(3. * cm)
0069 {
0070 new PerspectiveVisActionMessenger(this);
0071 }
0072
0073
0074
0075 void PerspectiveVisAction::Draw()
0076 {
0077 fpVisManager = G4VVisManager::GetConcreteInstance();
0078 if (fpVisManager) {
0079
0080
0081 if (fScene == "room-and-chair") {
0082 RoomAndChair();
0083 }
0084 }
0085 }
0086
0087
0088
0089 void PerspectiveVisAction::RoomAndChair()
0090 {
0091
0092 G4VisAttributes room_visAtts(G4Colour::Red());
0093 room_visAtts.SetForceWireframe(true);
0094 ExtendedDraw(G4Box("box", fRoomX, fRoomY, fRoomZ), room_visAtts, G4TranslateZ3D(fRoomZ));
0095
0096
0097 G4Box("window", fWindowX, fWindowY, fWindowZ);
0098 ExtendedDraw(G4Box("window-x", fWindowX, fWindowY, fWindowZ), room_visAtts,
0099 G4Translate3D(-fRoomX - fWindowX, fWindowOffset, fWindowY + fWindowSillHeight));
0100 ExtendedDraw(G4Box("window-y1", fWindowX, fWindowY, fWindowZ), room_visAtts,
0101 G4Translate3D(0., -fRoomY - fWindowX, fWindowY + fWindowSillHeight)
0102 * G4RotateZ3D(90. * deg));
0103 ExtendedDraw(G4Box("window-y2", fWindowX, fWindowY, fWindowZ), room_visAtts,
0104 G4Translate3D(0., fRoomY + fWindowX, fWindowY + fWindowSillHeight)
0105 * G4RotateZ3D(-90. * deg));
0106
0107
0108 ExtendedDraw(G4Box("door-frame", fDoorFrameX, fDoorFrameY, fDoorFrameZ), room_visAtts,
0109 G4Translate3D(-fRoomX - fDoorFrameX, fDoorFrameOffset, fDoorFrameZ));
0110 ExtendedDraw(G4Box("door", fDoorX, fDoorY, fDoorZ), room_visAtts,
0111 G4Translate3D(-fRoomX - fDoorX, fDoorFrameOffset, fDoorZ) * G4TranslateY3D(fDoorY)
0112 * G4RotateZ3D(60. * deg)
0113 * G4TranslateY3D(-fDoorY));
0114
0115
0116 G4VisAttributes chair_visAtts(G4Colour::Cyan());
0117 G4Transform3D A = G4RotateZ3D(90. * deg);
0118 G4Transform3D B = G4RotateY3D(90. * deg);
0119 G4Transform3D C = G4RotateZ3D(-20. * deg);
0120 G4Transform3D D = G4TranslateZ3D(fChairY);
0121 G4Transform3D E = G4TranslateY3D(-0.5 * fRoomY);
0122 G4Transform3D chair_transform = E * D * C * B * A;
0123 Chair(chair_visAtts, chair_transform);
0124 }
0125
0126
0127
0128 void PerspectiveVisAction::Chair(const G4VisAttributes& visAtts, const G4Transform3D& transform)
0129 {
0130
0131 ExtendedDraw(G4Box("chair-back", fChairX, fChairThickness, fChairZ - fChairSeat), visAtts,
0132 transform * G4Translate3D(0., -fChairY + fChairThickness, fChairZ + fChairSeat));
0133 ExtendedDraw(G4Box("chair-seat", fChairX, fChairY, fChairThickness), visAtts,
0134 transform * G4TranslateZ3D(-fChairThickness + 2. * fChairSeat));
0135 for (int i = -1; i < 2; i += 2) {
0136 for (int j = -1; j < 2; j += 2) {
0137 ExtendedDraw(
0138 G4Box("chair-leg", fChairThickness, fChairThickness, fChairSeat - fChairThickness), visAtts,
0139 transform
0140 * G4Translate3D(i * (fChairX - fChairThickness), j * (fChairY - fChairThickness),
0141 fChairSeat - fChairThickness));
0142 }
0143 }
0144 }
0145
0146
0147
0148 void PerspectiveVisAction::ExtendedDraw(const G4VSolid& solid, const G4VisAttributes& visAtts,
0149 const G4Transform3D& transform)
0150 {
0151 static const G4double extender = 100. * m;
0152 static const G4Vector3D x(1, 0, 0);
0153 static const G4Vector3D y(0, 1, 0);
0154 static const G4Vector3D z(0, 0, 1);
0155
0156
0157 G4bool any = false, A = false, X = false, Y = false, Z = false;
0158 if (G4StrUtil::contains(fOptionString, "a")) {
0159 A = true;
0160 any = true;
0161 }
0162 if (G4StrUtil::contains(fOptionString, "x")) {
0163 X = true;
0164 any = true;
0165 }
0166 if (G4StrUtil::contains(fOptionString, "y")) {
0167 Y = true;
0168 any = true;
0169 }
0170 if (G4StrUtil::contains(fOptionString, "z")) {
0171 Z = true;
0172 any = true;
0173 }
0174 if (any) {
0175 G4Polyhedron* polyhedron = solid.GetPolyhedron();
0176 G4bool isAuxEdgeVisible = false;
0177 G4bool notLastFace;
0178 do {
0179 G4int n;
0180 G4Point3D nodes[4];
0181 notLastFace = polyhedron->GetNextFacet(n, nodes);
0182 G4bool notLastEdge;
0183 do {
0184 G4Point3D v1, v2;
0185 G4int edgeFlag;
0186 notLastEdge = polyhedron->GetNextEdge(v1, v2, edgeFlag);
0187 if (isAuxEdgeVisible || edgeFlag > 0) {
0188 G4Vector3D v21 = v2 - v1;
0189
0190 G4Vector3D v21a = v21;
0191 v21a.transform(transform);
0192
0193 using namespace std;
0194 if (A || (Z && abs(v21a.z()) > sqrt(v21a.x() * v21a.x() + v21a.y() * v21a.y()))
0195 || (X && abs(v21a.x()) > sqrt(v21a.y() * v21a.y() + v21a.z() * v21a.z()))
0196 || (Y && abs(v21a.y()) > sqrt(v21a.x() * v21a.x() + v21a.x() * v21a.z())))
0197 {
0198 G4Polyline edge;
0199 edge.SetVisAttributes(G4Colour(.2, .2, .2));
0200 edge.push_back(v1 - extender * v21.unit());
0201 edge.push_back(v2 + extender * v21.unit());
0202 fpVisManager->Draw(edge, transform);
0203 }
0204 }
0205 } while (notLastEdge);
0206 } while (notLastFace);
0207 }
0208
0209
0210 fpVisManager->Draw(solid, visAtts, transform);
0211 }
0212
0213