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