2287 {
2288
2291
2293 if (!pScene) {
2295 G4warn <<
"ERROR: No current scene. Please create one." <<
G4endl;
2296 }
2297 return;
2298 } else {
2302 << "ERROR: Scene has no extent. Add volumes or use \"/vis/scene/add/extent\"."
2304 }
2305 return;
2306 }
2307 }
2308
2309 G4double userLength, red, green, blue, xmid, ymid, zmid;
2310 G4String userLengthUnit, direction, placement, positionUnit;
2311 std::istringstream is (newValue);
2312 is >> userLength >> userLengthUnit >> direction
2313 >> red >> green >> blue
2314 >> placement
2315 >> xmid >> ymid >> zmid >> positionUnit;
2316
2318 const G4VisExtent& sceneExtent = pScene->
GetExtent();
2319 if (userLengthUnit == "auto") {
2321 const G4double intLog10Length = std::floor(std::log10(lengthMax));
2322 length = std::pow(10,intLog10Length);
2323 if (5.*length < lengthMax) length *= 5.;
2324 else if (2.*length < lengthMax) length *= 2.;
2325 } else {
2327 }
2328 G4String annotation =
G4BestUnit(length,
"Length");
2329
2331 xmid *= unit; ymid *= unit; zmid *= unit;
2332
2333 Scale::Direction scaleDirection (Scale::x);
2334 if (direction[0] == 'y') scaleDirection = Scale::y;
2335 if (direction[0] == 'z') scaleDirection = Scale::z;
2336
2338 if (!pViewer) {
2341 "ERROR: G4VisCommandSceneAddScale::SetNewValue: no viewer."
2342 "\n Auto direction needs a viewer."
2344 }
2345 return;
2346 }
2347
2352
2353 if (direction == "auto") {
2354 if (std::abs(vp.
x()) > std::abs(vp.
y()) &&
2355 std::abs(vp.
x()) > std::abs(vp.
z())) {
2356 if (std::abs(up.
y()) > std::abs(up.
z())) scaleDirection = Scale::z;
2357 else scaleDirection = Scale::y;
2358 }
2359 else if (std::abs(vp.
y()) > std::abs(vp.
x()) &&
2360 std::abs(vp.
y()) > std::abs(vp.
z())) {
2361 if (std::abs(up.
x()) > std::abs(up.
z())) scaleDirection = Scale::z;
2362 else scaleDirection = Scale::x;
2363 }
2364 else if (std::abs(vp.
z()) > std::abs(vp.
x()) &&
2365 std::abs(vp.
z()) > std::abs(vp.
y())) {
2366 if (std::abs(up.
y()) > std::abs(up.
x())) scaleDirection = Scale::x;
2367 else scaleDirection = Scale::y;
2368 }
2369 }
2370
2371 G4bool autoPlacing =
false;
if (placement ==
"auto") autoPlacing =
true;
2372
2373
2374
2375 const G4double halfLength(length / 2.);
2377 const G4double freeLengthFraction (1. + 2. * comfort);
2378
2385
2386
2389 worried = true;
2392 "WARNING: Existing scene does not yet have any extent."
2393 "\n Maybe you have not yet added any geometrical object."
2395 }
2396 }
2397
2398
2400 switch (scaleDirection) {
2401 case Scale::x:
2402 if (freeLengthFraction * (xmax - xmin) < length) room = false;
2403 break;
2404 case Scale::y:
2405 if (freeLengthFraction * (ymax - ymin) < length) room = false;
2406 break;
2407 case Scale::z:
2408 if (freeLengthFraction * (zmax - zmin) < length) room = false;
2409 break;
2410 }
2411 if (!room) {
2412 worried = true;
2415 "WARNING: Not enough room in existing scene. Maybe scale is too long."
2417 }
2418 }
2419 if (worried) {
2422 "WARNING: The scale you have asked for is bigger than the existing"
2423 "\n scene. Maybe you have added it too soon. It is recommended that"
2424 "\n you add the scale last so that it can be correctly auto-positioned"
2425 "\n so as not to be obscured by any existing object and so that the"
2426 "\n view parameters can be correctly recalculated."
2428 }
2429 }
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454 G4double sxmid(xmid), symid(ymid), szmid(zmid);
2455 if (autoPlacing) {
2456
2457
2458 const G4double xComfort = comfort * (xmax - xmin);
2459 const G4double yComfort = comfort * (ymax - ymin);
2460 const G4double zComfort = comfort * (zmax - zmin);
2461 switch (scaleDirection) {
2462 case Scale::x:
2464 sxmid = xmax + xComfort;
2465 symid = ymin - yComfort;
2466 szmid = zmin - zComfort;
2467 } else {
2468 sxmid = xmin - xComfort;
2469 symid = ymin - yComfort;
2470 szmid = zmax + zComfort;
2471 }
2472 break;
2473 case Scale::y:
2475 sxmid = xmin - xComfort;
2476 symid = ymax + yComfort;
2477 szmid = zmin - zComfort;
2478 } else {
2479 sxmid = xmax + xComfort;
2480 symid = ymin - yComfort;
2481 szmid = zmin - zComfort;
2482 }
2483 break;
2484 case Scale::z:
2486 sxmid = xmax + xComfort;
2487 symid = ymin - yComfort;
2488 szmid = zmax + zComfort;
2489 } else {
2490 sxmid = xmin - xComfort;
2491 symid = ymin - yComfort;
2492 szmid = zmax + zComfort;
2493 }
2494 break;
2495 }
2496 }
2497
2501 G4VisExtent scaleExtent(-h,h,-t,t,-t,t);
2502 switch (scaleDirection) {
2503 case Scale::x:
2504 break;
2505 case Scale::y:
2507 break;
2508 case Scale::z:
2510 break;
2511 }
2513 scaleExtent = scaleExtent.Transform(transform);
2514
2515 G4Colour colour(red, green, blue);
2516 if (direction == "auto") {
2517 switch (scaleDirection) {
2518 case Scale::x:
2520 break;
2521 case Scale::y:
2523 break;
2524 case Scale::z:
2526 break;
2527 }
2528 }
2529 G4VisAttributes visAttr(colour);
2530
2531 Scale* scale = new Scale
2532 (visAttr, length, transform,
2534 G4VModel* model = new G4CallbackModel<Scale>(scale);
2539
2540 const G4String& currentSceneName = pScene -> GetName ();
2541 G4bool successful = pScene -> AddRunDurationModel (model, warn);
2542 if (successful) {
2544 G4cout <<
"Scale of " << annotation
2545 << " added to scene \"" << currentSceneName << "\".";
2547 G4cout <<
"\n with extent " << scaleExtent
2550 }
2552 }
2553 }
2555
2557}
HepGeom::Vector3D< G4double > G4Vector3D
G4GLOB_DLL std::ostream G4cout
const G4VisExtent & GetExtent() const
static G4double ValueOf(const char *unitName)
void SetType(const G4String &)
void SetGlobalDescription(const G4String &)
void SetGlobalTag(const G4String &)
void SetExtent(const G4VisExtent &)
const G4ViewParameters & GetViewParameters() const
static G4double fCurrentTextSize
void G4VisCommandsSceneAddUnsuccessful(G4VisManager::Verbosity verbosity)
void CheckSceneAndNotifyHandlers(G4Scene *=nullptr)
static G4VisManager * fpVisManager
const G4Vector3D & GetViewpointDirection() const
const G4Vector3D & GetUpVector() const
G4double GetExtentRadius() const