Non-Modal scripting is possible, but needs care

PraxisPraxis Posts: 252

There are a couple of other threads on this topic:

  1. http://www.daz3d.com/forums/discussion/65903/any-way-to-allow-scene-to-be-accessed-when-script-is-open/p1
  2. http://www.daz3d.com/forums/discussion/comment/657812/#Comment_657812

03 May 2016: Edited by Praxis to remove offensive content.

Sorry folks - it seemed like a good idea at the time, but it wasn't. (See Rob's post below).

 

Post edited by Praxis on

Comments

  • PraxisPraxis Posts: 252

    A correction:

    Line 67 should read:

    //    (See line 371 for an attempt to prevent this)

     

  • rbtwhizrbtwhiz Posts: 2,250
    edited May 2016

    Because something can be done does not necessarily mean that it should be done.

    My comment in the linked post, while not stated in said post, is taking into consideration the inefficiency of introducing a local event loop in the context of a script, as well as the associated timing issues it presents. I didn't have the time (or energy) to explain what can (easily) go wrong by introducing a local event loop and how one might go about dealing with the inherent problems in introducing one (not to mention the platform differences), so I chose not to open that can of worms. I gave "the short answer" immediately followed by "the longer answer," but I intentionally omitted "the long answer" because I felt it would have been a roadmap for basically this. I see now that perhaps I explained a little too much; because what I explained is now being used as reference for something I specifically did not want to promote. Perhaps I should have let Richard's response stand as is and allowed that be the end of it; this ability has existed in the scripting API for quite a while (i.e., 3.0.1.3 - late February 2009) without anyone apparently noticing hints in scripts that ship with the application as plain text.

    Yes, as you've noticed, you can indeed create a local loop in which you call Global::processEvents() and allow the application continue to "do its thing." I demonstrate this in the Render To RIB sample, where I use DzProcess to start the ridepends utility and allow the application to respond to events that were triggered prior to the script's execution (and any triggered by the running process) while waiting for the utility (and then the script) to terminate. Notice, however, that I use that particular mechanism in a way that is blocking as far as user interaction is concerned... and for good reason.

    That all being said, do what you feel you must for your own purposes. Just be aware that QA is instructed to flag any use of non-modal dialogs in extensions submitted for distribution through the store as a matter of course. As I stated in the linked post, "modeless dialogs" are accomplished through DzPane subclasses in Daz Studio.

    -Rob

    Post edited by rbtwhiz on
  • PraxisPraxis Posts: 252
    rbtwhiz said:

    Because something can be done does not necessarily mean that it should be done.

    Thanks for replying, Rob - I guess your answer to my
        "Q3) Is there anything else that needs to be done to ensure that a Non-Modal script behaves nicely?"
      is: "Yes - don't run it".

    To that I'll add that on my system (Studio v4.8, Win7-64bit) I've since found that (inadvertently) launching a

    second instance of the script hangs Studio and requires a visit to Task Manager to "End Program".

    Sorry for causing you trouble - perhaps it would be best to just delete this thread?

    -P

     

  • rbtwhizrbtwhiz Posts: 2,250

    To be completely honest, it was actually kind of refreshing to see the obvious thought being put into solving the problem; I do not want to discourage that in the least. It's just that I am intimately familiar with what is happening under the hood and what the likely result would be, so I try to steer folks away from the things that I know will cause them (or others who like to copy/paste code without truely understanding what that code is doing) problems.

    I'll leave the decision of whether or not to delete the thread up to you. It doesn't bother me to be here. If you do want the thread removed, flag the first post to let the moderators know and they'll take care of it.

    -Rob

  • PraxisPraxis Posts: 252

    Thanks for the nice comment.

    I appreciate that its a fine line between providing help, and providing info that is likely to build problems for us and you later.

    So... If it doesn't bother you, let's leave this thread on the board as useful official feedback on the topic.

    -P

  • V3DigitimesV3Digitimes Posts: 3,150
    edited May 2016

    Several times I've felt it would be really something better if I could access at least the camera orbit when the users use my scripts. Knowing that the QA  would not accept "non modal" methods with scripts (and that I would be too afraid to "bug" the system), I see 2 ways to have this possible :

    1. using sdk to make pluggin instead of script.

    2. "fake", somehow, the camera orbit mode in my interface. 

     

    In the second case, I was wondering if it was possible. I can easily swap or move cameras via script, which tends to show that the viewport is not "frozen", but I was wondering if it was possible to fake the orbit view control in a scripted interface. It is linked to mouse location and moves, but can these mouse "elements" be accessed in scripts?

    Post edited by V3Digitimes on
  • PraxisPraxis Posts: 252
    edited May 2016

    Several times I've felt it would be really something better if I could access at least the camera orbit when the users use my scripts. Knowing that the QA  would not accept "non modal" methods with scripts (and that I would be too afraid to "bug" the system), I see 2 ways to have this possible :

    1. using sdk to make pluggin instead of script.

    2. "fake", somehow, the camera orbit mode in my interface. 

     

    In the second case, I was wondering if it was possible. I can easily swap or move cameras via script, which tends to show that the viewport is not "frozen", but I was wondering if it was possible to fake the orbit view control in a scripted interface. It is linked to mouse location and moves, but can these mouse "elements" be accessed in scripts?

    LOL - That's exactly why I tried going the non-modal route:  Half the area of my huge modal dialog is being used to provide single-click access to local equivalents of the Viewport controls: Camera Selector, Camera Orbit/Rotate/Pan/Dolly/Zoom/Frame/Aim/Reset, and DrawStyle.  I even added a DzCheckBox to toggle display of Bones.  It all works well enough, except for the Camera Orbit, Rotate, Pan, and Dolly controls, which sort-of work, but not properly.  I couldn't find a way to do the mouse stuff in script, so I'm using DzFloatSliders for them.

    There are Actions for most Camera controls: DzRotateCameraLeftAction, etc. - but not for controlling Orbit.

    It would be nice to be able to do something like this in script:

    MainWindow.PaneMgr().temporarilyReparentViewPaneInto( oMyModalDialog.wCameraGroup );

     

    Post edited by Praxis on
  • PraxisPraxis Posts: 252

    For what it's worth, this is as far as I got with the Orbit control.  It Orbits, but not quite like the equivalent Viewport control, and only around the Y-Axis.

    (Sorry about the non-standard naming conventions)

    // Camera Y-Orbit Angle (degrees):varprxPRC_ViewCamOrbit_Sld             = new DzFloatSlider( prxPRC_ViewCam_Grp );prxPRC_ViewCamOrbit_Sld.label       = "Y-Orbit:";prxPRC_ViewCamOrbit_Sld.max         =  180;prxPRC_ViewCamOrbit_Sld.min         = -180;prxPRC_ViewCamOrbit_Sld.clamped     = true;prxPRC_ViewCamOrbit_Sld.sensitivity = 1;prxPRC_ViewCamOrbit_Sld.valueChanged.connect( prxPRC_ViewCamOrbit_ProcessChange );// To prevent recursion between Model and Controller code:var prxPRC_IgnoreControlChanges = false;//------------------------------------function  prxPRC_ActiveCamera()       // : DzCamera{  return MainWindow.getViewportMgr().getActiveViewport().get3DViewport().getCamera();};  // prxPRC_ActiveCamera()//------------------------------------function  prxPRC_ViewCamLoadControlsFromViewport()   // : void{  // Load the Control settings fromn the current Viewport Camera  var ThisCam           = prxPRC_ActiveCamera();  if( ThisCam ) {    //---Calculate the Camera data---    var CamWSPos        = ThisCam.getWSPos();         // : DzVec3    var OrbitPos        = ThisCam.getFocalPoint();    // : DzVec3    // As per prxPRC_ViewCamOrbit_ProcessChange():    //  Angle of Orbit around the World-Y axis thru the FocalPoint:    var Angle           = Math.atan2( (CamWSPos.z - OrbitPos.z), (CamWSPos.x - OrbitPos.x) );    // Angle is in the range -PI .. PI    var AngleOrbitDeg   = (Angle * 180) / Math.PI;    // Convert Radians to Degrees    //---Load the Camera data into our Controls---    // Prevent recursion:    var WasIgnoreControlChanges = prxPRC_IgnoreControlChanges;    prxPRC_IgnoreControlChanges = true;    try {      prxPRC_ViewCamOrbit_Sld  .value = AngleOrbitDeg;      // ...etc. for other controls    } finally {      prxPRC_IgnoreControlChanges = WasIgnoreControlChanges;    }  }};  // prxPRC_ViewCamLoadControlsFromViewport()//------------------------------------function  prxPRC_ViewCamOrbit_ProcessChange()   // : void{  // Prevent recursion:  if( !prxPRC_IgnoreControlChanges ) {    // Orbit the Camera about its FocalPoint    var ThisCam         = prxPRC_ActiveCamera();    if( ThisCam ) {      // Cannot Orbit an Ortho Camera:      if(    ( ThisCam.type == DzCamera.PERSPECTIVE_CAMERA )          || ( ThisCam.type == DzCamera.GENERAL_CAMERA )        ) {        // Convert Angle in degrees (-180.0 .. 180.0) to radians (-pi .. pi):        var AngleRad    = Math.PI * (prxPRC_ViewCamOrbit_Sld.value / 180);        // Orbit around the FocalPoint, Maintaining FocalDistance and CameraHeight:        var CamPos      = ThisCam.getWSPos();         // : DzVec3        var OrbitPos    = ThisCam.getFocalPoint();    // : DzVec3        var Radius      = ThisCam.focalDistance;      // : Number        // This Orbits around the World-Y axis thru the FocalPoint, i.e. parallel to the Y=0=Ground_Plane:        //  (Not around the Camera's local Y-Axis)        var NewPos      = new DzVec3( OrbitPos.x + (Radius * Math.sin( AngleRad ) )                                    , OrbitPos.y                                    , OrbitPos.z + (Radius * Math.cos( AngleRad ) )                                    );//      NewPos.y        = CamPos.y;     // $TODO ???        ThisCam.setWSPos( NewPos );        // Now re-Orient the Camera to point at the original FocalPoint:        prxPRC_Active3DViewport().aimCamera();        // $TODO ???: It's still not quite right...        // Update other Controls:        prxPRC_ViewCamLoadControlsFromViewport();      }   // Can Orbit    } // We have a Camera  } // Prevent recursion};  // prxPRC_ViewCamOrbit_ProcessChange()

     

  • PraxisPraxis Posts: 252

    Several times I've felt it would be really something better if I could access at least the camera orbit when the users use my scripts. Knowing that the QA  would not accept "non modal" methods with scripts (and that I would be too afraid to "bug" the system), I see 2 ways to have this possible :

    1. using sdk to make pluggin instead of script.

    2. "fake", somehow, the camera orbit mode in my interface. 

     

    In the second case, I was wondering if it was possible. I can easily swap or move cameras via script, which tends to show that the viewport is not "frozen", but I was wondering if it was possible to fake the orbit view control in a scripted interface. It is linked to mouse location and moves, but can these mouse "elements" be accessed in scripts?

    I've fixed-up my earlier attempt, and I think it probably now does what you want.  I've posted it in a new thread for this "Orbit Camera" topic: a-script-to-orbit-camera-around-a-point

    -P

     

  • V3DigitimesV3Digitimes Posts: 3,150
    edited May 2016

    Hi Praxis, very nice job - very smart - thank you so much for the principle and for the link!

    I stupidely had not make the link between an orbit mode and the spherical coordinates(!!!). For this, really shame on me! 

    Plus I was focused on have "the same" as in the interface, catching the mouse moves. Looking at what you did I think I'll add in my script some dials, and use spherical to cartesian and cartesian to spherical conversion too. Very very useful thanks!

    Post edited by V3Digitimes on
  • PraxisPraxis Posts: 252

    Hi Praxis, very nice job - very smart - thank you so much for the principle and for the link!

    Thank you for the nice words again.

    I have posted a new thread, with much better Orbit controls (using your idea to orbit the bounding box), plus controls for Ortho Cameras, plus other stuff that I find useful in a modal dialog.  I hope you will some of it useful too: a-script-to-control-a-selected-property-with-large-font-size-and-preview-buttons

  • V3DigitimesV3Digitimes Posts: 3,150
    edited May 2016

    Nice! I had not time to test it so far, but this looks very promising. I love anyway any tools which allows to improve the workflow! Browsing between tabs is not my passion in life :)

    Thanks for sharing!

    Post edited by V3Digitimes on
Sign In or Register to comment.