Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Wie ruft man POVRAY aus einem Programm heraus auf ? (https://www.delphipraxis.net/35458-wie-ruft-man-povray-aus-einem-programm-heraus-auf.html)

em-sigma 7. Dez 2004 14:45


Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Hallo zusammen,

ich bin gerade dabei, einen Material-Editor für POV-Ray zu basteln (ja, ich weiß gibt's schon tausendfach, aber es ist nicht so einfach, eine nette Aufgabe zu finden, bei der man auch was lernen kann).

Bisher habe ich den Aufruf über CreateProcess gemacht (siehe Code). Aber das hat den Nachteil, daß man warten muß, bis das Bild fertig ist, was manchmal ganz schön lange dauert).
Außerdem verwende ich hier eine DOS-Version von POV-Ray, die es aber nur bis zur Version 3.1g gibt (inzwischen gibt es V3.6 für Windows). Diese alte Version hat den Vorteil, daß man einen Programmlauf per Kommandozeile abwickeln kann.

Jetzt die Frage: Weiß jemand, wie ich etwas Entsprechendes mit der Windows-Version zustande kriege? Es sollte kein Fenster aufpoppen. Wie stelle ich fest, daß der Prozess fertig ist ? (Beim Starten von POV-Ray erscheint immer ein Begrüßungsschirm, also sollte das Programm möglichst nur einmal gestartet werden)

Hilfe!

Vielen Dank schon mal im Voraus,

Greetings, em-sigma

Delphi-Quellcode:
procedure TMaterialEditor.ButtonPreviewClick(Sender: TObject);
var
   StartUpInfo:TStartUpInfo;
   ProcessInfo:TProcessInformation;
begin
   FillChar(StartUpInfo,SizeOf(TStartUpInfo),0);
   StartUpInfo.cb:=SizeOf(TStartUpInfo);
   StartUpInfo.dwFlags:=STARTF_USESHOWWINDOW;
   StartUpInfo.wShowWindow:=SW_HIDE;

   If CreateProcess(nil,
                    PChar('runpov.bat +imy.pov -d'),
                    nil,
                    nil,
                    False,
                    NORMAL_PRIORITY_CLASS,
                    nil,
                    nil,
                    StartUpInfo,
                    ProcessInfo)
      then begin WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
   end;

   TGAImage.LoadFromFile('my.tga');
end;

Luckie 7. Dez 2004 14:48

Re: Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Zitat:

Zitat von em-sigma
Bisher habe ich den Aufruf über CreateProcess gemacht (siehe Code). Aber das hat den Nachteil, daß man warten muß, bis das Bild fertig ist, was manchmal ganz schön lange dauert).

Das zeigt mir, dass du den Quellcode, den du benutzt nicht verstanden hast. Nimm das MSDN-Library durchsuchenWaiteForSingleObject raus.

em-sigma 7. Dez 2004 16:17

Re: Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Hallo Luckie,

ohne WaitForSingleObject zeigt das Programm aber das zuvor generierte Bild an und nicht das, an dem POV-Ray gerade arbeitet.

MfG, em-sigma

matthiasl 28. Jul 2007 19:31

Re: Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Hallo Leute,

gab es zu der Frage, ob man die Windows-Version "im Stillen" aufrufen kann, jemals eine Antwort?
Ich stehe gerade vor dem selben Thema.

Wie kann ich PovRay dazu nutzen, im Hintergrund nette Bildchen zu berechnen, während ein Bild als Vollbild angezeigt wird?

Nette Grüße...
...Matthias

mkinzler 28. Jul 2007 19:36

Re: Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Rufe Povray ohne Anzeige auf und stelle das Bild mit deinem Programm dar.

em-sigma 30. Jul 2007 08:32

Re: Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Hallo Matthias,

ich weiß ja nicht, ob du mit den bisherigen Antworten was anfangen konntest - ich konnte es jedenfalls nicht.

Glücklicherweise habe ich dann doch noch selbst eine Lösung gefunden, die für kleine Bilder ganz gut geeignet ist.

Dazu besorgst du dir aus dem Internet zunächst einmal das MegaPOV-Paket. Da ist eine Kommando-Zeilen-Version dabei, die still und leise im Hintergrund arbeitet. MegaPOV ist mit POVRay fast identisch, enthält nur zusätzliche Features.

Der Aufruf geschieht dann wie folgt

Delphi-Quellcode:
var
   StartupInfo:TStartUpInfo;
   ProcessInfo:TProcessInformation;
begin
   ...
   FillChar(StartUpInfo,SizeOf(TStartUpInfo),0);
   StartUpInfo.cb:=SizeOf(TStartUpInfo);
   StartUpInfo.dwFlags:=STARTF_USESHOWWINDOW;
   StartUpInfo.wShowWindow:=SW_HIDE;
   If CreateProcess(nil,
                    PChar('megapov +I'+name+'.pov +W'+IntToStr(w)+' +H'+IntToStr(h)+' +A0.3 -D'),
                    nil,
                    nil,
                    false,
                    NORMAL_PRIORITY_CLASS,
                    nil,
                    nil,
                    StartUpInfo,
                    ProcessInfo) then begin
       WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
   end;
   TGAImage.LoadFromFile(name+'.tga');
   ...
end;
Sieht nicht schön aus, funktioniert aber. 'name' ist der Name der gewünschten Datei (ohne Extension). 'w' ist die Breite und 'h' die Höhe. MegaPOV erzeugt TGA-Dateien, deshalb brauchst du noch eine Unit zum Einlesen von TGA-Dateien.

Viel Spaß beim Rendern, em-sigma

matthiasl 6. Aug 2007 17:38

Re: Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Zitat:

Zitat von em-sigma
ich weiß ja nicht, ob du mit den bisherigen Antworten was anfangen konntest - ich konnte es jedenfalls nicht.

Ich konnte es auch nicht. Aber das ist genau das, was ich wissen wollte.

Zwischendurch habe ich versucht, den PovRay-Quelltext selber zu kompilieren, aber der OpenWatcom hatte diverse Probleme mit den Template-Strukturen, so daß ich nach einigen Tagen aufgegeben habe. Dann hab ich versucht YafRay dafür zu benutzen, weil er sich von Haus aus viel besser dafür eignet, und habe dafür keine Dokumentation der XML-Beschreibungssprache gefunden.

Das dieses Thema so schwierig erscheint wundert mich doch sehr. Ich frage mich, ob es so ungewöhnlich ist, daß ein Programm mal ein schönes Diagramm o. ä. zeigen will?

Dein Vorschlag hat sehr gut funktioniert. Danke.

Ich werde die Variante mit dem eigenen durchkompilieren vom Original-Pov-Ray nicht aus dem Auge verlieren. Dazu hab ich mir den Intel-C-Compiler bestellt und hoffe das der diese sehr futuristische Programmierung versteht. :-)

Ich finde die Idee, ein Diagramm, einen Statusbericht oder evtl sogar einfach nur ein wenig Fensterdekoration rendern zu lassen, richtig lauschig und genial. Besonders, wenn es sich um eine benutzerseitig generierbare Scriptsprache handelt.

Wenn das mal funktioniert, werde ich hier einen Bericht dazu ablegen. Bis dahin gilt der Text von en-sigma als Stand der Dinge.

...Matthias...

mrpix777 2. Dez 2021 15:24

AW: Wie ruft man POVRAY aus einem Programm heraus auf ?
 
Tja, ist schon eine Weile her, daß diese Frage gestellt wurde!
Ich starte schon sehr lange das PovRay Rendering Programm (http://www.povray.org/) von meinem 3d-Programm aus.
Eine etwas umfangreichere Lösung zur gestellten Frage möchte ich allen Interessierten nicht vorenthalten, da man sonst zu diesem Thema eher wenig detaillierte Infos erhält.

Das Testprogramm geht wie folgt vor:
- übergebene Programmparameter checken
- Startkommando aus Registry checken
- ev. eigenes Startkommando verwenden
- PovRay starten und dabei Bild als PNG-Datei speichern

Übrigens, der Unterschied der beiden Exe-Dateien ist beachtlich! :wink:

Delphi-Quellcode:
//********************************************************************
// Project File:  PovRayStarter.dpr v1.02   2021-01-03
// A Delphi console example program for starting 'PovRay rendering'.
// PovRayStarter.exe tested with: Delphi-6 release with     8.704 Bytes
//                                 Delphi-Sydney-CE with 1.162.752 Bytes
// Ref.: https://www.delphipraxis.net/35458-wie-ruft-man-povray-aus-einem-programm-heraus-auf.html
//********************************************************************
{$D+,L+,Y+,R+,S+,Q+,O-,C+}   // debug
{$D-,L-,Y-,R-,S-,Q-,O-,C-}   // release

{$APPTYPE CONSOLE}

program PovRayStarter;

uses SysUtils, ShellApi, Windows, Registry;

const
  NL = #13#10;  // NewLine = carriage return + linefeed
  PovRayStartCommand36 = 'C:/Program Files/POV_Ray/POV-Ray 3.6/bin/pvengine.exe +FP ';
  PovRayStartCommand37 = 'C:/Program Files/POV_Ray/POV-Ray 3.7/bin/pvengine.exe ';
  // set your individual start command here:
  PovRayStartCommand37b= 'E:\Programming_Tools\POV_Ray\POV-Ray_3.7\bin\pvengine32-sse2.exe';

var
  povStartCommand, povStartParams: string;

//*********************************************************
// Gets a string value from the registry from the given root and sub key.
// Converts integer value to a string
// Returns '', if the sub key or value name are unknown.
//---------------------------------------------------------
function GetRegistryString (const rootKey: HKEY;
                            const subKey, name: string): string;
var
  reg: TRegistry;           // registry access object
  valueInfo: TRegDataInfo;  // info about registry value
begin
  Result := '';
  reg := TRegistry.Create;
  try
    reg.RootKey := rootKey;
    if reg.OpenKeyReadOnly (subKey)
    then if reg.GetDataInfo (name, valueInfo) // check if registry value is string or integer
    then begin
      case valueInfo.RegData of
        // string value: just return it
        rdString, rdExpandString:  Result := reg.ReadString (name);
        // integer value: convert to string
        rdInteger:  Result := IntToStr (reg.ReadInteger(name));
      end;
    end;
  finally
    reg.CloseKey;
    reg.Free;
  end;
end;
//*********************************************************
// get start command of PovRay Renderer
//---------------------------------------------------------
procedure GetPovRayStartCommand;
var si: integer;
begin
  povStartCommand := paramStr(1);
  if povStartCommand = ''
  then begin
    povStartCommand := GetRegistryString (HKEY_CLASSES_ROOT
                    , '\Applications\pvengine.exe\shell\open\Command', '');
    if povStartCommand <> ''
    then begin
      // cut text after 'pvengine.exe"'
      si := pos('pvengine.exe"', povStartCommand);
      if si > 0
      then delete (povStartCommand, si+13, 999);
    end;
  end;
  if povStartCommand = ''
  then povStartCommand := PovRayStartCommand36;
  if povStartCommand = '' then
    povStartCommand := PovRayStartCommand37;
  writeln ('Start command of PovRay program : '#13#10,' ', povStartCommand);
end;
//*********************************************************
// execute Windows application
// input:   name: string    application name
//           param: string   application start parameters
// result:  boolean         =true application started
//           errorCode       e.g. 2 = ERROR_FILE_NOT_FOUND
// see:     https://docwiki.embarcadero.com/RADStudio/Sydney/en/Input-Output_Errors
// examples: started := RunApplication ('pvengine.exe', '/RENDER example.pov');
//           started := RunApplication ('ReadMe.txt', ''); // view text file
//           RunApplication ('notepad', 'info.txt');       // view text file with notePad
//           RunApplication ('Explorer', 'C:\');           // start windows explorer
//---------------------------------------------------------
function RunApplication (const name, param: string): boolean;
var  errorCode: cardinal;
begin
  writeln (NL,'try starting PovRay with command...', NL, name, param);

  errorCode := ShellExecute (0, 'open', PChar(name), PChar(param), nil, SW_SHOWNORMAL);

  result := (errorCode = 0) or (errorCode = 42);
  if result
  then writeln (' successfully started ')
  else writeln ('RunApplication: ', NL
               ,' can not start application ''', name+param, '''' + NL
               ,' error code = ' + IntToStr(errorCode));

  // german info from Delphi-Praxis:
  //   https://www.delphipraxis.net/126563-shellexecute-error.html
end;
//*********************************************************
// start rendering of povray scene
//---------------------------------------------------------
procedure StartPovRayRendering (const povfilename: string);
var
  result: boolean;
begin
  povStartParams := ' /EDIT ' + povfilename
                  + ' /RENDER ' + povfilename
                  + ' +FN';  // PNG output see http://www.povray.org/documentation/view/3.6.1/219/

  // try to start PovRay 3.6
  result := RunApplication (povStartCommand, povStartParams);
  if not result
  // try to start PovRay 3.7b
  then RunApplication (PovRayStartCommand37b, povStartParams);
end;
//*********************************************************
// create povray test scene file
//---------------------------------------------------------
procedure SavePovRayTestFile (const povfilename: string);
var pov: text;
begin
  Assign (pov, povfilename);
  ReWrite (pov);
  writeln (pov, '// File: ' + povfilename, NL
              , 'camera {location -3*z}', NL
              , 'light_source {<9,9,-9> 1 parallel}', NL
              , 'sphere {0 1 pigment {rgb<1,1,0.5>}}', NL);
  Close (pov);
end;
//*********************************************************
const
  povFilename = 'Test1.pov';
begin
  writeln (NL, '=== PovRayStarter v1.02 ===', NL);
  SavePovRayTestFile (povFilename);
  GetPovRayStartCommand;
  StartPovRayRendering (povFilename);
  sleep(7000);
end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz