2225 {
2226
2229
2231 if (!pScene) {
2233 G4warn <<
"ERROR: No current scene. Please create one." <<
G4endl;
2234 }
2235 return;
2236 } else {
2240 << "ERROR: Scene has no extent. Add volumes or use \"/vis/scene/add/extent\"."
2242 }
2243 return;
2244 }
2245 }
2246
2247 G4double userLength, red, green, blue, xmid, ymid, zmid;
2248 G4String userLengthUnit, direction, placement, positionUnit;
2249 std::istringstream is (newValue);
2250 is >> userLength >> userLengthUnit >> direction
2251 >> red >> green >> blue
2252 >> placement
2253 >> xmid >> ymid >> zmid >> positionUnit;
2254
2257 if (userLengthUnit == "auto") {
2259 const G4double intLog10Length = std::floor(std::log10(lengthMax));
2260 length = std::pow(10,intLog10Length);
2261 if (5.*length < lengthMax) length *= 5.;
2262 else if (2.*length < lengthMax) length *= 2.;
2263 } else {
2265 }
2267
2269 xmid *= unit; ymid *= unit; zmid *= unit;
2270
2271 Scale::Direction scaleDirection (Scale::x);
2272 if (direction[0] == 'y') scaleDirection = Scale::y;
2273 if (direction[0] == 'z') scaleDirection = Scale::z;
2274
2276 if (!pViewer) {
2279 "ERROR: G4VisCommandSceneAddScale::SetNewValue: no viewer."
2280 "\n Auto direction needs a viewer."
2282 }
2283 return;
2284 }
2285
2290
2291 if (direction == "auto") {
2292 if (std::abs(vp.
x()) > std::abs(vp.
y()) &&
2293 std::abs(vp.
x()) > std::abs(vp.
z())) {
2294 if (std::abs(up.
y()) > std::abs(up.
z())) scaleDirection = Scale::z;
2295 else scaleDirection = Scale::y;
2296 }
2297 else if (std::abs(vp.
y()) > std::abs(vp.
x()) &&
2298 std::abs(vp.
y()) > std::abs(vp.
z())) {
2299 if (std::abs(up.
x()) > std::abs(up.
z())) scaleDirection = Scale::z;
2300 else scaleDirection = Scale::x;
2301 }
2302 else if (std::abs(vp.
z()) > std::abs(vp.
x()) &&
2303 std::abs(vp.
z()) > std::abs(vp.
y())) {
2304 if (std::abs(up.
y()) > std::abs(up.
x())) scaleDirection = Scale::x;
2305 else scaleDirection = Scale::y;
2306 }
2307 }
2308
2309 G4bool autoPlacing =
false;
if (placement ==
"auto") autoPlacing =
true;
2310
2311
2312
2313 const G4double halfLength(length / 2.);
2315 const G4double freeLengthFraction (1. + 2. * comfort);
2316
2323
2324
2327 worried = true;
2330 "WARNING: Existing scene does not yet have any extent."
2331 "\n Maybe you have not yet added any geometrical object."
2333 }
2334 }
2335
2336
2338 switch (scaleDirection) {
2339 case Scale::x:
2340 if (freeLengthFraction * (xmax - xmin) < length) room = false;
2341 break;
2342 case Scale::y:
2343 if (freeLengthFraction * (ymax - ymin) < length) room = false;
2344 break;
2345 case Scale::z:
2346 if (freeLengthFraction * (zmax - zmin) < length) room = false;
2347 break;
2348 }
2349 if (!room) {
2350 worried = true;
2353 "WARNING: Not enough room in existing scene. Maybe scale is too long."
2355 }
2356 }
2357 if (worried) {
2360 "WARNING: The scale you have asked for is bigger than the existing"
2361 "\n scene. Maybe you have added it too soon. It is recommended that"
2362 "\n you add the scale last so that it can be correctly auto-positioned"
2363 "\n so as not to be obscured by any existing object and so that the"
2364 "\n view parameters can be correctly recalculated."
2366 }
2367 }
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392 G4double sxmid(xmid), symid(ymid), szmid(zmid);
2393 if (autoPlacing) {
2394
2395
2396 const G4double xComfort = comfort * (xmax - xmin);
2397 const G4double yComfort = comfort * (ymax - ymin);
2398 const G4double zComfort = comfort * (zmax - zmin);
2399 switch (scaleDirection) {
2400 case Scale::x:
2402 sxmid = xmax + xComfort;
2403 symid = ymin - yComfort;
2404 szmid = zmin - zComfort;
2405 } else {
2406 sxmid = xmin - xComfort;
2407 symid = ymin - yComfort;
2408 szmid = zmax + zComfort;
2409 }
2410 break;
2411 case Scale::y:
2413 sxmid = xmin - xComfort;
2414 symid = ymax + yComfort;
2415 szmid = zmin - zComfort;
2416 } else {
2417 sxmid = xmax + xComfort;
2418 symid = ymin - yComfort;
2419 szmid = zmin - zComfort;
2420 }
2421 break;
2422 case Scale::z:
2424 sxmid = xmax + xComfort;
2425 symid = ymin - yComfort;
2426 szmid = zmax + zComfort;
2427 } else {
2428 sxmid = xmin - xComfort;
2429 symid = ymin - yComfort;
2430 szmid = zmax + zComfort;
2431 }
2432 break;
2433 }
2434 }
2435
2440 switch (scaleDirection) {
2441 case Scale::x:
2442 break;
2443 case Scale::y:
2445 break;
2446 case Scale::z:
2448 break;
2449 }
2451 scaleExtent = scaleExtent.Transform(transform);
2452
2454 if (direction == "auto") {
2455 switch (scaleDirection) {
2456 case Scale::x:
2458 break;
2459 case Scale::y:
2461 break;
2462 case Scale::z:
2464 break;
2465 }
2466 }
2468
2469 Scale* scale = new Scale
2470 (visAttr, length, transform,
2477
2478 const G4String& currentSceneName = pScene -> GetName ();
2479 G4bool successful = pScene -> AddRunDurationModel (model, warn);
2480 if (successful) {
2482 G4cout <<
"Scale of " << annotation
2483 << " added to scene \"" << currentSceneName << "\".";
2485 G4cout <<
"\n with extent " << scaleExtent
2488 }
2490 }
2491 }
2493
2495}
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
G4Scene * GetCurrentScene() const
G4VViewer * GetCurrentViewer() const
static Verbosity GetVerbosity()