2223 {
2224
2227
2229 if (!pScene) {
2231 G4warn <<
"ERROR: No current scene. Please create one." <<
G4endl;
2232 }
2233 return;
2234 } else {
2238 << "ERROR: Scene has no extent. Add volumes or use \"/vis/scene/add/extent\"."
2240 }
2241 return;
2242 }
2243 }
2244
2245 G4double userLength, red, green, blue, xmid, ymid, zmid;
2246 G4String userLengthUnit, direction, placement, positionUnit;
2247 std::istringstream is (newValue);
2248 is >> userLength >> userLengthUnit >> direction
2249 >> red >> green >> blue
2250 >> placement
2251 >> xmid >> ymid >> zmid >> positionUnit;
2252
2255 if (userLengthUnit == "auto") {
2257 const G4double intLog10Length = std::floor(std::log10(lengthMax));
2258 length = std::pow(10,intLog10Length);
2259 if (5.*length < lengthMax) length *= 5.;
2260 else if (2.*length < lengthMax) length *= 2.;
2261 } else {
2263 }
2265
2267 xmid *= unit; ymid *= unit; zmid *= unit;
2268
2269 Scale::Direction scaleDirection (Scale::x);
2270 if (direction[0] == 'y') scaleDirection = Scale::y;
2271 if (direction[0] == 'z') scaleDirection = Scale::z;
2272
2274 if (!pViewer) {
2277 "ERROR: G4VisCommandSceneAddScale::SetNewValue: no viewer."
2278 "\n Auto direction needs a viewer."
2280 }
2281 return;
2282 }
2283
2288
2289 if (direction == "auto") {
2290 if (std::abs(vp.
x()) > std::abs(vp.
y()) &&
2291 std::abs(vp.
x()) > std::abs(vp.
z())) {
2292 if (std::abs(up.
y()) > std::abs(up.
z())) scaleDirection = Scale::z;
2293 else scaleDirection = Scale::y;
2294 }
2295 else if (std::abs(vp.
y()) > std::abs(vp.
x()) &&
2296 std::abs(vp.
y()) > std::abs(vp.
z())) {
2297 if (std::abs(up.
x()) > std::abs(up.
z())) scaleDirection = Scale::z;
2298 else scaleDirection = Scale::x;
2299 }
2300 else if (std::abs(vp.
z()) > std::abs(vp.
x()) &&
2301 std::abs(vp.
z()) > std::abs(vp.
y())) {
2302 if (std::abs(up.
y()) > std::abs(up.
x())) scaleDirection = Scale::x;
2303 else scaleDirection = Scale::y;
2304 }
2305 }
2306
2307 G4bool autoPlacing =
false;
if (placement ==
"auto") autoPlacing =
true;
2308
2309
2310
2311 const G4double halfLength(length / 2.);
2313 const G4double freeLengthFraction (1. + 2. * comfort);
2314
2321
2322
2325 worried = true;
2328 "WARNING: Existing scene does not yet have any extent."
2329 "\n Maybe you have not yet added any geometrical object."
2331 }
2332 }
2333
2334
2336 switch (scaleDirection) {
2337 case Scale::x:
2338 if (freeLengthFraction * (xmax - xmin) < length) room = false;
2339 break;
2340 case Scale::y:
2341 if (freeLengthFraction * (ymax - ymin) < length) room = false;
2342 break;
2343 case Scale::z:
2344 if (freeLengthFraction * (zmax - zmin) < length) room = false;
2345 break;
2346 }
2347 if (!room) {
2348 worried = true;
2351 "WARNING: Not enough room in existing scene. Maybe scale is too long."
2353 }
2354 }
2355 if (worried) {
2358 "WARNING: The scale you have asked for is bigger than the existing"
2359 "\n scene. Maybe you have added it too soon. It is recommended that"
2360 "\n you add the scale last so that it can be correctly auto-positioned"
2361 "\n so as not to be obscured by any existing object and so that the"
2362 "\n view parameters can be correctly recalculated."
2364 }
2365 }
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 G4double sxmid(xmid), symid(ymid), szmid(zmid);
2391 if (autoPlacing) {
2392
2393
2394 const G4double xComfort = comfort * (xmax - xmin);
2395 const G4double yComfort = comfort * (ymax - ymin);
2396 const G4double zComfort = comfort * (zmax - zmin);
2397 switch (scaleDirection) {
2398 case Scale::x:
2400 sxmid = xmax + xComfort;
2401 symid = ymin - yComfort;
2402 szmid = zmin - zComfort;
2403 } else {
2404 sxmid = xmin - xComfort;
2405 symid = ymin - yComfort;
2406 szmid = zmax + zComfort;
2407 }
2408 break;
2409 case Scale::y:
2411 sxmid = xmin - xComfort;
2412 symid = ymax + yComfort;
2413 szmid = zmin - zComfort;
2414 } else {
2415 sxmid = xmax + xComfort;
2416 symid = ymin - yComfort;
2417 szmid = zmin - zComfort;
2418 }
2419 break;
2420 case Scale::z:
2422 sxmid = xmax + xComfort;
2423 symid = ymin - yComfort;
2424 szmid = zmax + zComfort;
2425 } else {
2426 sxmid = xmin - xComfort;
2427 symid = ymin - yComfort;
2428 szmid = zmax + zComfort;
2429 }
2430 break;
2431 }
2432 }
2433
2438 switch (scaleDirection) {
2439 case Scale::x:
2440 break;
2441 case Scale::y:
2443 break;
2444 case Scale::z:
2446 break;
2447 }
2449 scaleExtent = scaleExtent.Transform(transform);
2450
2452 if (direction == "auto") {
2453 switch (scaleDirection) {
2454 case Scale::x:
2456 break;
2457 case Scale::y:
2459 break;
2460 case Scale::z:
2462 break;
2463 }
2464 }
2466
2467 Scale* scale = new Scale
2468 (visAttr, length, transform,
2475
2476 const G4String& currentSceneName = pScene -> GetName ();
2477 G4bool successful = pScene -> AddRunDurationModel (model, warn);
2478 if (successful) {
2480 G4cout <<
"Scale of " << annotation
2481 << " added to scene \"" << currentSceneName << "\".";
2483 G4cout <<
"\n with extent " << scaleExtent
2486 }
2488 }
2489 }
2491
2493}
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()