Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte » 

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi wie kann ich bestimmte Infos aus Textdokument einlesen? (https://www.delphipraxis.net/168443-wie-kann-ich-bestimmte-infos-aus-textdokument-einlesen.html)

Boyington 21. Mai 2012 20:54

wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Hallo Leute,
weiß Jemand vielleicht, wie ich alle Koordinaten aus einem Textdokument (*.stl Datei im ASCII Format) einlesen und dann in einer Liste speichern kann? Da ich mich mit Text- oder StringVerarbeitung in Delphi nicht gut auskenne.

*.stl Datei (ASCII Format) sieht wie folgendes aus:

Code:
solid ascii
  facet normal 2.445222e-016 0.000000e+000 1.000000e+000
    outer loop
      vertex  -2.007874e+000 1.968504e+000 5.905512e-002
      vertex  -2.007874e+000 -1.968504e+000 5.905512e-002
      vertex  -1.574803e-001 -1.968504e+000 5.905512e-002
    endloop
  endfacet
  facet normal 2.445222e-016 -5.090141e-032 1.000000e+000
    outer loop
      vertex  -1.574803e-001 -1.968504e+000 5.905512e-002
      vertex  -1.574803e-001 1.968504e+000 5.905512e-002
      vertex  -2.007874e+000 1.968504e+000 5.905512e-002
    endloop
  endfacet
.
.
.
.
 facet normal 7.071068e-001 -1.471962e-016 7.071068e-001
    outer loop
      vertex  -1.574803e-001 1.968504e+000 5.905512e-002
      vertex  -1.574803e-001 -1.968504e+000 5.905512e-002
      vertex  -3.937008e-002 -1.968504e+000 -5.905512e-002
    endloop
  endfacet
endsolid
Jedes 3D-Objekt besteht aus vielen kleinen Dreiecken und jedes Dreieck besteht aus 1x normal (Nomalvektor) und 3x vertex (Koordinaten der 3 Eckpunkten von jedem Dreieck).

Meine Frage ist: wie kann ich vom Anfang bis zum Ende der *.stl Datei alle Normalvektoren (als type: TVektor) und alle Koordinaten der 3 Eckpunkten von jedem Dreieck in einer Liste speichern (die Liste soll dynamisch sein, weil die Länge der Liste vorher nicht bekannt ist)?

Typen sehen ungefähr wie folgendes aus:
Code:
type
  TVektor = record
    x, y, z: real;
  end;
  TDreieck = record
    n: TVektor; // n ist Normalvektor
    p: array[1..3] of TVektor; //p hat Koordinaten von 3 Eckpunkten
  end;
.
.
.
.
Var
  hDreieck : ^TDreieck;
Ich bitte euch um die Hilfe und bin sehr dankbar für die Antwort wie immer ;-)

Gruss
Lee

Amateurprofi 21. Mai 2012 23:44

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Versuch es mal hiermit.
Ich habe die von dir gezeigten daten ins Clipboard kopiert
und von dort in die StringList geschrieben.
Alle Daten wurden korrekt gelesen.
Du solltest das mit list.LoadFromFile machen.
Delphi-Quellcode:
type
   TVektor = record
     x, y, z: real;
   end;
   TDreieck = record
     n: TVektor; // n ist Normalvektor
     p: array[1..3] of TVektor; //p hat Koordinaten von 3 Eckpunkten
   end;
Var
   hDreieck : ^TDreieck;
   Dreiecke:Array of TDreieck;

PROCEDURE TMain.Test;
const
   recstart='facet normal';
   recline='vertex';
var list:TStrings; line:integer; data:TDreieck;
FUNCTION FindLine(const s:string; raiseerr:boolean):boolean;
begin
   while (line<list.count) and (Copy(Trim(list[line]),1,Length(s))<>s) do inc(line);
   if line<list.count then result:=true
      else if not raiseerr then result:=false
         else raise Exception.Create(s+' nicht gefunden.');
end;
FUNCTION ReadNumber(const s:string; var i:integer):real;
var j:integer;
begin
   j:=i;
   while s[j]<>' ' do dec(j);
   result:=StrToFloat(Copy(s,j+1,i-j));
   while s[j]=' ' do dec(j);
   i:=j;
end;
PROCEDURE ReadLine(var v:TVektor);
var s:string; i:integer;
begin
   s:=Trim(list[line]);
   i:=Length(s);
   v.z:=ReadNumber(s,i);
   v.y:=ReadNumber(s,i);
   v.x:=ReadNumber(s,i);
   inc(line);
end;
PROCEDURE ReadRecord;
var i:integer;
begin
   ReadLine(data.n);
   for i:=1 to 3 do begin
      FindLine(recline,true);
      ReadLine(data.p[i]);
   end;
   SetLength(Dreiecke,Length(Dreiecke)+1);
   Dreiecke[High(dreiecke)]:=data;
end;
// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt
begin
   Dreiecke:=nil;
   list:=TStringList.Create;
   try
      try
         list.text:=Clipboard.AsText;
         // oder List.LoadFromFile('Filename');
         line:=0;
         while FindLine(recstart,false) do ReadRecord;
      except
         On E:Exception do begin
            ShowMessage(E.Message);
            Dreiecke:=nil;
         end;
      end;
   finally
      list.free;
   end;
end;

Boyington 22. Mai 2012 07:34

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Morgen alle,
vielen Dank für die nette Antwort, Klaus!
Ich werde später selbst auch mal probieren, ob die bei mir geht.

l.g
Lee

Boyington 23. Mai 2012 23:27

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Zitat:

Zitat von Amateurprofi (Beitrag 1167521)
Versuch es mal hiermit.
Ich habe die von dir gezeigten daten ins Clipboard kopiert
und von dort in die StringList geschrieben.
Alle Daten wurden korrekt gelesen.
Du solltest das mit list.LoadFromFile machen.
Delphi-Quellcode:
type
   TVektor = record
     x, y, z: real;
   end;
   TDreieck = record
     n: TVektor; // n ist Normalvektor
     p: array[1..3] of TVektor; //p hat Koordinaten von 3 Eckpunkten
   end;
Var
   hDreieck : ^TDreieck;
   Dreiecke:Array of TDreieck;

PROCEDURE TMain.Test;
const
   recstart='facet normal';
   recline='vertex';
var list:TStrings; line:integer; data:TDreieck;
FUNCTION FindLine(const s:string; raiseerr:boolean):boolean;
begin
   while (line<list.count) and (Copy(Trim(list[line]),1,Length(s))<>s) do inc(line);
   if line<list.count then result:=true
      else if not raiseerr then result:=false
         else raise Exception.Create(s+' nicht gefunden.');
end;
FUNCTION ReadNumber(const s:string; var i:integer):real;
var j:integer;
begin
   j:=i;
   while s[j]<>' ' do dec(j);
   result:=StrToFloat(Copy(s,j+1,i-j));
   while s[j]=' ' do dec(j);
   i:=j;
end;
PROCEDURE ReadLine(var v:TVektor);
var s:string; i:integer;
begin
   s:=Trim(list[line]);
   i:=Length(s);
   v.z:=ReadNumber(s,i);
   v.y:=ReadNumber(s,i);
   v.x:=ReadNumber(s,i);
   inc(line);
end;
PROCEDURE ReadRecord;
var i:integer;
begin
   ReadLine(data.n);
   for i:=1 to 3 do begin
      FindLine(recline,true);
      ReadLine(data.p[i]);
   end;
   SetLength(Dreiecke,Length(Dreiecke)+1);
   Dreiecke[High(dreiecke)]:=data;
end;
// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt
begin
   Dreiecke:=nil;
   list:=TStringList.Create;
   try
      try
         list.text:=Clipboard.AsText;
         // oder List.LoadFromFile('Filename');
         line:=0;
         while FindLine(recstart,false) do ReadRecord;
      except
         On E:Exception do begin
            ShowMessage(E.Message);
            Dreiecke:=nil;
         end;
      end;
   finally
      list.free;
   end;
end;

Guten Abend, Leute
Zwei Fragen an dich, Klaus:

1)für SetLength(Dreiecke,Length(Dreiecke)+1), Length(Dreiecke)+1 darf nur zwischen 0...255 sein, oder? Wenn ein 3D-Objekt z.B nur aus weniger als 255 Dreiecken besteht, ist es in Ordnung, aber wenn es aus 10000 Dreiecken besteht, wie mache ich mit dieser Funktion Dreiecke[256], Dreiecke[257]....bis Dreiecke[10000]?

2)wie kann man nach dem Einlesen der *.stl Datei und nach dem Schreiben aller Koordinaten in Variable "Dreiecke"(array of TDreieck) alle dort gespeicherte Koordinaten wieder in Clipboard kopieren? Damit kann ich alle in Variable "Dreiecke" gespeicherten Koordinaten mit den original Koordinaten mal vergleichen und überprüfen, ob es richtig ist.

Danke für die Antwort im Voraus!

l.g
Lee

Amateurprofi 24. Mai 2012 01:43

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Zitat:

Zitat von Boyington (Beitrag 1167809)
Guten Abend, Leute
Zwei Fragen an dich, Klaus:

1)für SetLength(Dreiecke,Length(Dreiecke)+1), Length(Dreiecke)+1 darf nur zwischen 0...255 sein, wenn ein 3D-Objekt nur aus weniger als 255 Dreiecken besteht, ist es in Ordnung, aber wenn das 3D-Objekt aus 10000 Dreiecken besteht, wie mache ich mit dieser Funktion Dreiecke[256], Dreiecke[257]....bis Dreiecke[10000]?

2)wie kann man nach dem Einlesen der *.stl Datei und nach dem Schreiben aller Koordinaten in Variable "Dreiecke"(array of TDreieck) alle dort gespeicherte Koordinaten wieder in Clipboard kopieren? Damit kann ich die original Koordinaten mit allen in Variable "Dreiecke" gespeicherten Koordinaten mal vergleichen und überprüfen, ob es richtig ist.

Danke für die Antwort im Voraus!

l.g
Lee

@Lee:

Zu (1) :
Wie kommst du auf die Beschränkung bei SetLength?
Ein dynamisches Array kannst du High(integer) lang machen.
Somit dürfte die einzige Beschränkung der verfügbare Speicherplatz sein.

Zu (2) :
So :
Delphi-Quellcode:
PROCEDURE CopyDreiecke(tofile:boolean);
var list:TStrings;
FUNCTION ToStr(v:real):String;
begin
   result:=FloatToStrF(v,ffExponent,7,3)+' ';
   if result[1]<>'-' then result:=' '+result;
end;
PROCEDURE AddVector(const v:TVektor);
type TxVector=Array[0..2] of real;
var s,s1:string; i:integer;
begin
   for i:=0 to High(TxVector) do s:=s+ToStr(TxVector(v)[i]);
   list.Add(s);
end;
var i,j:integer;
begin
   list:=TStringList.Create;
   try
      try
         if Length(Dreiecke)=0 then
            raise Exception.Create('Dreiecke ist leer.');
         for i:=0 to High(Dreiecke) do
            with Dreiecke[i] do begin
               AddVector(n);
               for j:=Low(p) to High(p) do AddVector(p[j]);
               list.Add('');
            end;
         if tofile then list.SaveToFile(ExtractFilePath(ParamStr(0))+'Log.txt')
            else Clipboard.AsText:=List.Text;
         ShowMessage('fertig.');
      except
         On E:Exception do ShowMessage(E.Message);
      end;
   finally
      list.free;
   end;
end;
Mit CopyDreiecke(false) stellst du die Daten ins Clipboard, mit CopyDreiecke(true) in die Datei "Log.txt" im Programmverzeichnis.

Boyington 24. Mai 2012 07:31

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Zitat:

Zitat von Amateurprofi (Beitrag 1167827)
Zitat:

Zitat von Boyington (Beitrag 1167809)
Guten Abend, Leute
Zwei Fragen an dich, Klaus:

1)für SetLength(Dreiecke,Length(Dreiecke)+1), Length(Dreiecke)+1 darf nur zwischen 0...255 sein, wenn ein 3D-Objekt nur aus weniger als 255 Dreiecken besteht, ist es in Ordnung, aber wenn das 3D-Objekt aus 10000 Dreiecken besteht, wie mache ich mit dieser Funktion Dreiecke[256], Dreiecke[257]....bis Dreiecke[10000]?

2)wie kann man nach dem Einlesen der *.stl Datei und nach dem Schreiben aller Koordinaten in Variable "Dreiecke"(array of TDreieck) alle dort gespeicherte Koordinaten wieder in Clipboard kopieren? Damit kann ich die original Koordinaten mit allen in Variable "Dreiecke" gespeicherten Koordinaten mal vergleichen und überprüfen, ob es richtig ist.

Danke für die Antwort im Voraus!

l.g
Lee

@Lee:

Zu (1) :
Wie kommst du auf die Beschränkung bei SetLength?
Ein dynamisches Array kannst du High(integer) lang machen.
Somit dürfte die einzige Beschränkung der verfügbare Speicherplatz sein.

Zu (2) :
So :
Delphi-Quellcode:
PROCEDURE CopyDreiecke(tofile:boolean);
var list:TStrings;
FUNCTION ToStr(v:real):String;
begin
   result:=FloatToStrF(v,ffExponent,7,3)+' ';
   if result[1]<>'-' then result:=' '+result;
end;
PROCEDURE AddVector(const v:TVektor);
type TxVector=Array[0..2] of real;
var s,s1:string; i:integer;
begin
   for i:=0 to High(TxVector) do s:=s+ToStr(TxVector(v)[i]);
   list.Add(s);
end;
var i,j:integer;
begin
   list:=TStringList.Create;
   try
      try
         if Length(Dreiecke)=0 then
            raise Exception.Create('Dreiecke ist leer.');
         for i:=0 to High(Dreiecke) do
            with Dreiecke[i] do begin
               AddVector(n);
               for j:=Low(p) to High(p) do AddVector(p[j]);
               list.Add('');
            end;
         if tofile then list.SaveToFile(ExtractFilePath(ParamStr(0))+'Log.txt')
            else Clipboard.AsText:=List.Text;
         ShowMessage('fertig.');
      except
         On E:Exception do ShowMessage(E.Message);
      end;
   finally
      list.free;
   end;
end;
Mit CopyDreiecke(false) stellst du die Daten ins Clipboard, mit CopyDreiecke(true) in die Datei "Log.txt" im Programmverzeichnis.


Morgen Alle,
alles klar, danke für die hilfreiche Antwort:)

l.g
Lee

Boyington 28. Mai 2012 14:08

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Hallo Klaus,
ich hab dein Programm vereinfacht, aber es funktioniert einfach nicht (die *.exe Datei kann nicht mehr geschlossen werden nach der Durchführung), es scheint, dass Fehler irgendwo aufgetreten sind (wegen unendlicher Schleife???).

Code:
type
   TVektor = record
     x, y, z: real;
   end;
   TDreieck = record
     n: TVektor; // n ist Normalvektor
     p: array[1..3] of TVektor; //p hat Koordinaten von 3 Eckpunkten
   end;
Var
   Dreiecke:Array of TDreieck;


function ReadNumber(const s:string; var i:integer):real;
var
j:integer;
begin
j:=i;
while s[j]<>' ' do dec(j);
 result:=StrToFloat(Copy(s,j+1,i-j));
while s[j]=' ' do dec(j);
 i:=j;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  s1='facet normal';
  s2='vertex';
  s3='endsolid';

var
  s:string;
  //i:integer;
  j:integer;
  L:integer;
  List:TStrings;
  Line:integer;
  data:TDreieck;

begin
   Dreiecke:=nil;
   List:=TStringList.Create;
   List.LoadFromFile(OpenDialog1.FileName);
   Line:=1;

   while (Copy(Trim(List[Line]),1,Length(s3))<>s3) do
   begin
    s:=Trim(List[Line]);
    L:=Length(s);

    if (Copy(s,1,Length(s1))=s1) then
      begin
       data.n.z:=ReadNumber(s,L);
       data.n.y:=ReadNumber(s,L);
       data.n.x:=ReadNumber(s,L);
       inc(Line);

       while (Copy(s,1,Length(s2))<>s2) do inc(Line);
         for j:=1 to 3 do begin
          data.p[j].z:=ReadNumber(s,L);
          data.p[j].y:=ReadNumber(s,L);
          data.p[j].x:=ReadNumber(s,L);
          inc(line);
         end;

       SetLength(Dreiecke,Length(Dreiecke)+1);
       Dreiecke[High(dreiecke)]:=data;
      end

       else inc(Line);
    end;
end;
könntest du vielleicht für mich die Fehler mal suchen und dann korrigieren?
Vielen Dank!

lg
Lee

Amateurprofi 28. Mai 2012 22:51

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Zitat:

Zitat von Boyington (Beitrag 1168374)
Hallo Klaus,
ich hab dein Programm vereinfacht, aber es funktioniert einfach nicht (die *.exe Datei kann nicht mehr geschlossen werden nach der Durchführung), es scheint, dass Fehler irgendwo aufgetreten sind (wegen unendlicher Schleife???).

Code:
type
   TVektor = record
     x, y, z: real;
   end;
   TDreieck = record
     n: TVektor; // n ist Normalvektor
     p: array[1..3] of TVektor; //p hat Koordinaten von 3 Eckpunkten
   end;
Var
   Dreiecke:Array of TDreieck;


function ReadNumber(const s:string; var i:integer):real;
var
j:integer;
begin
j:=i;
while s[j]<>' ' do dec(j);
 result:=StrToFloat(Copy(s,j+1,i-j));
while s[j]=' ' do dec(j);
 i:=j;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  s1='facet normal';
  s2='vertex';
  s3='endsolid';

var
  s:string;
  //i:integer;
  j:integer;
  L:integer;
  List:TStrings;
  Line:integer;
  data:TDreieck;

begin
   Dreiecke:=nil;
   List:=TStringList.Create;
   List.LoadFromFile(OpenDialog1.FileName);
   Line:=1;

   while (Copy(Trim(List[Line]),1,Length(s3))<>s3) do
   begin
    s:=Trim(List[Line]);
    L:=Length(s);

    if (Copy(s,1,Length(s1))=s1) then
      begin
       data.n.z:=ReadNumber(s,L);
       data.n.y:=ReadNumber(s,L);
       data.n.x:=ReadNumber(s,L);
       inc(Line);

       while (Copy(s,1,Length(s2))<>s2) do inc(Line);
         for j:=1 to 3 do begin
          data.p[j].z:=ReadNumber(s,L);
          data.p[j].y:=ReadNumber(s,L);
          data.p[j].x:=ReadNumber(s,L);
          inc(line);
         end;

       SetLength(Dreiecke,Length(Dreiecke)+1);
       Dreiecke[High(dreiecke)]:=data;
      end

       else inc(Line);
    end;
end;
könntest du vielleicht für mich die Fehler mal suchen und dann korrigieren?
Vielen Dank!

lg
Lee

Hallo Lee,
eigentlich verspüre ich keine große Lust den Korrektor zu spielen, wenn jemand, dem ich einen perfekt funktionierenden
Code lieferte, diesen vermeintlich "vereinfacht" und in nicht funktionierenden Code umwandelt.
Hab's mir trotzdem mal angeschaut, und ohne viel zu suchen tippe ich darauf dass das Programm in der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); festhängt.
Warum ?!
Weil du zwar korrekt den Zeilenzähler erhöhst, aber die neue Zeile nicht in s stellst.
In der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); prüfst du gegen s und das enthält "facet normal ...."
Also wird "vertex" nicht gefunden, und wenn du dann noch die Überlaufprüfung abgeschaltet hast ....

Was mir noch auffiel:
Du gibst List nicht frei.
Du sprachst in einem der Beiträge von 10000 Dreiecken.
Für 1 Dreieck werden ca. 270 Chars gebraucht für 10000 Dreiecke also 2.7 MB (oder 5.4 MB bei WideChars).
Irgendwann kriegst du dann eine Out of Memory Exception.

Das von mir gewählte Konstrukt sorgt dafür, dass
1) list immer freigegeben wird
2) Dreiecke auf nil gesetzt wird, wenn ein Fehler auftritt.
Deine "Vereinfachung" sorgt für
1) unsicheren Code
2) Memory Leaks

Denk mal darüber nach, ob solch eine Vereinfachung wirklich sinnvoll ist.

Boyington 29. Mai 2012 01:11

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Liste der Anhänge anzeigen (Anzahl: 2)
[QUOTE=Amateurprofi;1168431]
Zitat:

Zitat von Boyington (Beitrag 1168374)
Hallo Lee,
eigentlich verspüre ich keine große Lust den Korrektor zu spielen, wenn jemand, dem ich einen perfekt funktionierenden
Code lieferte, diesen vermeintlich "vereinfacht" und in nicht funktionierenden Code umwandelt.
Hab's mir trotzdem mal angeschaut, und ohne viel zu suchen tippe ich darauf dass das Programm in der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); festhängt.
Warum ?!
Weil du zwar korrekt den Zeilenzähler erhöhst, aber die neue Zeile nicht in s stellst.
In der Zeile while (Copy(s,1,Length(s2))<>s2) do inc(Line); prüfst du gegen s und das enthält "facet normal ...."
Also wird "vertex" nicht gefunden, und wenn du dann noch die Überlaufprüfung abgeschaltet hast ....

Was mir noch auffiel:
Du gibst List nicht frei.
Du sprachst in einem der Beiträge von 10000 Dreiecken.
Für 1 Dreieck werden ca. 270 Chars gebraucht für 10000 Dreiecke also 2.7 MB (oder 5.4 MB bei WideChars).
Irgendwann kriegst du dann eine Out of Memory Exception.

Das von mir gewählte Konstrukt sorgt dafür, dass
1) list immer freigegeben wird
2) Dreiecke auf nil gesetzt wird, wenn ein Fehler auftritt.
Deine "Vereinfachung" sorgt für
1) unsicheren Code
2) Memory Leaks

Denk mal darüber nach, ob solch eine Vereinfachung wirklich sinnvoll ist.

vielen Dank für die sehr ausführlichen Antwort und Hinweise, Klaus.
Ich hab dein erstes Programm (stl-Datei einlesen) gerade probiert, aber leider hab ich folgende Fehlermeldungen bekommen.


http://www.delphipraxis.net/attachme...1&d=1338246528

http://www.delphipraxis.net/attachme...1&d=1338246528

Wegen Fehlermeldung von "PROCEDURE TMain.Test;" (in erstem Bild) hab ich folgende code, die eigentlich zu Procedure TMain.Test gehört, in "procedure TForm1.Button2Click(Sender: TObject);" geschrieben.

const
recstart='facet normal';
recline='vertex';
var list:TStrings; line:integer; data:TDreieck;

Dann hab ich das Programm wieder durchgeführt durch Drücken von Button2 "Koordinaten der STL einlesen", bekomme ich zweite Fehlermeldung (in 2. Bild)

Boyington 29. Mai 2012 01:28

AW: wie kann ich bestimmte Infos aus Textdokument einlesen?
 
Folgende ist mein Programm (code von dir gemacht), durch Drücken von Button2 werden STL-Datei eingelesen, und durch Drücken von Button3 wird die Liste in Log.txt gespeichert.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, GLScene, GLMisc, GLVectorFileObjects, GLWin32Viewer, GLFileSTL,
  Menus, ComCtrls, StdCtrls, ExtCtrls, GLTexture, GLObjects, GLHUDObjects;

type
    TVektor = record
    x, y, z: real;
    end;

    TDreieck = record
    n: TVektor;
    p: array[1..3] of TVektor;
    end;
.
.
.
Var
  Form1: TForm1;
  Dreiecke:array of TDreieck;
.
.
.
//PROCEDURE TMain.Test; <--bekomme ich Fehlermeldun

FUNCTION FindLine(const s:string; raiseerr:boolean):boolean;
var
  line:integer;
  list:TStrings;
begin
   while (line<list.count) and (Copy(Trim(list[line]),1,Length(s))<>s) do inc(line);
   if line<list.count then result:=true
      else if not raiseerr then result:=false
         else raise Exception.Create(s+' nicht gefunden.');
end;


FUNCTION ReadNumber(const s:string; var i:integer):real;
var j:integer;
begin
   j:=i;
   while s[j]<>' ' do dec(j);
   result:=StrToFloat(Copy(s,j+1,i-j));
   while s[j]=' ' do dec(j);
   i:=j;
end;


PROCEDURE ReadLine(var v:TVektor);
var s:string; i:integer; list:TStrings; line:integer;
begin
   s:=Trim(list[line]);
   i:=Length(s);
   v.z:=ReadNumber(s,i);
   v.y:=ReadNumber(s,i);
   v.x:=ReadNumber(s,i);
   inc(line);
end;


PROCEDURE ReadRecord;
const recline='vertex';
var i:integer; data:TDreieck;
begin
   ReadLine(data.n);
   for i:=1 to 3 do begin
      FindLine(recline,true);
      ReadLine(data.p[i]);
   end;
   SetLength(Dreiecke,Length(Dreiecke)+1);
   Dreiecke[High(dreiecke)]:=data;
end;


// var f:TextFile; i,j:integer; // nur zur Kontrolle benutzt

PROCEDURE CopyDreiecke(tofile:boolean);
var list:TStrings;

FUNCTION ToStr(v:real):String;
begin
   result:=FloatToStrF(v,ffExponent,7,3)+' ';
   if result[1]<>'-' then result:=' '+result;
end;

PROCEDURE AddVector(const v:TVektor);
type TxVector=Array[0..2] of real;

var s:string; i:integer; list:TStrings;
begin
   for i:=0 to High(TxVector) do s:=s+ToStr(TxVector(v)[i]);
   list.Add(s);
end;

var i,j:integer;
begin
   list:=TStringList.Create;
   try
      try
         if Length(Dreiecke)=0 then
            raise Exception.Create('Dreiecke ist leer.');
         for i:=0 to High(Dreiecke) do
            with Dreiecke[i] do begin
               AddVector(n);
               for j:=Low(p) to High(p) do AddVector(p[j]);
               list.Add('');
            end;
         if tofile then list.SaveToFile(ExtractFilePath(ParamStr(0))+'Log.txt');
           //else Clipboard.AsText:=List.Text;
         ShowMessage('fertig.');
      except
         On E:Exception do ShowMessage(E.Message);
      end;
   finally
      list.free;
   end;
end;



procedure TForm1.Button3Click(Sender: TObject);
begin
CopyDreiecke(true);
end;

procedure TForm1.Button2Click(Sender: TObject);
const
   recstart='facet normal';
   recline='vertex';
var list:TStrings; line:integer; data:TDreieck;
begin
   Dreiecke:=nil;
   list:=TStringList.Create;
   try
      try
         //list.text:=Clipboard.AsText;
         List.LoadFromFile(OpenDialog1.FileName);        
         line:=0;
         while FindLine(recstart,false) do ReadRecord;
      except
         On E:Exception do begin
            ShowMessage(E.Message);
            Dreiecke:=nil;
         end;
      end;
   finally
      list.free;
   end;
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:24 Uhr.
Seite 1 von 4  1 23     Letzte » 

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