Enable use of POV-Ray for Windows (#225)

This pull request reflects code changes made to be able to use POV-Ray for Windows, Version 3.7.0.msvc10.win64.

The changes have been tested on Windows 10 but not on unix-like operating systems. However, I don't think the code for unix-like operating systems has been affected.

The reason for the changes is explained below.

1. The POV-Ray for Windows executable is named `pvengine64.exe` on 64-bit Windows, not `povray

I've created two modules `POVRay`, specified separately for `windows` and `unix`, that export `povrayApp :: String`, yielding the correct name of the executable. The function is used in place of `"povray"` (eg in `Reanimate.Driver.Check.hasPovray`).

2. Generated file names containing `$` cause problems under PowerShell, due to automatic variables, and file names on Windows are not case sensitive

I've changed the 64-character `alphabet` in `Reanimate.Cache.encodeInt` for a 32-character one which includes only capital letters and digits. This affects both Windows and unix-like operating systems. (An alternative would be versions of `encodeInt` specified differently for `windows` and `unix`.)

3. POV-Ray for Windows requires the special command line option `/EXIT` to return

I've moved `Reanimate.Povray.mkPovrayImage'` to the two modules `POVRay`. In the `windows` version, `/EXIT` is now added to the list of switches passed to the POV-Ray executable.

4. POV-Ray for Windows cannot parse switches enclosed in `""` as switches

The cause of the problem is described in more detail in the comments in the source code of module `POVRay`.

As a work around, in the `windows` version of `mkPovrayImage'`, the POV-Ray command is written to a temporary batch file and it is that batch file which is passed to `runCmd`.

Other matters

In addition to the above, POV-Ray 3.7 includes 'Script I\O Restrictions` which can prevent the writing of files. These need to be disabled in the POV-Ray for Windows GUI (under the Options menu).
This commit is contained in:
Mike Pilgrem 2021-10-16 09:20:34 +01:00 committed by GitHub
commit ceb727e8da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 21 deletions

66
windows/POVRay.hs Normal file
View file

@ -0,0 +1,66 @@
module POVRay
( povrayApp
, mkPovrayImage'
) where
import Data.Hashable (Hashable (hash))
import Data.Text (Text)
import qualified Data.Text as T (concat, pack)
import qualified Data.Text.IO as T (writeFile)
import Reanimate.Cache (cacheFile, encodeInt)
import Reanimate.Misc (requireExecutable, runCmd)
import Reanimate.Parameters (pNoExternals)
import System.FilePath (replaceExtension, (<.>))
import System.IO (hClose, hPutStrLn)
import System.IO.Temp (withSystemTempFile)
povrayApp :: String
povrayApp = "pvengine64" -- Assumes 64 bit Windows
mkPovrayImage' :: [String] -> Text -> IO FilePath
mkPovrayImage' _ _ | pNoExternals = pure "/povray/has/been/disabled"
mkPovrayImage' args script = cacheFile template $ \target -> do
exec <- requireExecutable povrayApp
let pov_file = replaceExtension target "pov"
exec' = '"' : exec ++ "\"" -- Wrap exec in "" because the path is likely
-- to includes spaces
otherArgs = [ "-D"
, "+UA"
, "+I" ++ pov_file
, "+O" ++ target
, "/EXIT" -- Note [/EXIT special command-line option]
]
command = concatMap (' ':) (exec' : args ++ otherArgs)
T.writeFile pov_file script
-- Note [Use of a batch file]
withSystemTempFile "pvcommand.bat" $ \path h -> do
hPutStrLn h command
hClose h
runCmd path []
where
template = encodeInt (hash key) <.> "png"
key = T.concat (script:map T.pack args)
{-
Note [/EXIT special command-line option]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"The /EXIT command tells POV-Ray to perform the render given by the other
command-line options, combined with previously-set options such as internal
command-line settings, INI file, source file, and so forth, and then to exit. By
default, if this switch is not present, POV-Ray for Windows will remain running
after the render is complete. This switch only applies to renders started by
other options on the command-line. It will not affect renders started manually
from within POV-Ray for Windows itself."
source: https://www.povray.org/documentation/view/3.6.1/603/
Note [Use of batch file]
~~~~~~~~~~~~~~~~~~~~~~~~
POV-Ray for Windows assumes that anything on the command-line that is not a
switch is the name of an INI file. Switches are preceded by a plus or minus.
However, System.Process.createProcess_ wraps all arguments in "". POV_Ray for
Windows appears to interpret a switch wrapped in "" as the name of an INI file.
The work around used here is to write the POV-Ray command line to a batch file.
-}