unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,
  DirectXGraphics, DXGUtils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    Model, Normals : TList;
    procedure CalcNormals;
    procedure LoadDXF (const FileName : String);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

{$WARNINGS OFF}
procedure TForm1.LoadDXF (const FileName : String);
var
  f : TextFile;
  wrkString : String;
  group, err : Integer;
  x1, x2, y1, y2, z1, z2, x3, y3, z3 : Single;

procedure AddToList (const X, Y, Z : Single);
var
  pwrkVector : ^TD3DVector;
begin
  New (pwrkVector);
  pwrkVector^ := D3DVector (X, Y, Z);
  Model.Add (pwrkVector);
end;

begin
  AssignFile(f, FileName);
  Reset(f);
  repeat
    ReadLn(f, wrkString);
  until (wrkString = 'ENTITIES') or eof(f);
  while not eof (f) do begin
      ReadLn (f, group);
      ReadLn (f, wrkString);
      case group of
         0: begin
            AddToList (x3, y3, z3);
            AddToList (x2, y2, z2);
            AddToList (x1, y1, z1);
            end;
        10: val(wrkString, x1, err);
        20: val(wrkString, y1, err);
        30: val(wrkString, z1, err);
        11: val(wrkString, x2, err);
        21: val(wrkString, y2, err);
        31: val(wrkString, z2, err);
        12: val(wrkString, x3, err);
        22: val(wrkString, y3, err);
        32: val(wrkString, z3, err);
      end;
  end;
  CloseFile(f);
end;
{$WARNINGS ON}

procedure TForm1.CalcNormals;
var
  i : Integer;
  wrki, vx1, vy1, vz1, vx2, vy2, vz2 : Single;
  nx, ny, nz : Single;
  wrkVector : TD3DVector;
  pwrkVector : ^TD3DVector;
  wrkVector1, wrkVector2, wrkVector3 : TD3DVector;
  pwrkVector1, pwrkVector2, pwrkVector3 : ^TD3DVector;
begin
  for i := 0 to Model.Count div 3 - 1 do begin
     pwrkVector1 := Model [i * 3 + 1];
     wrkVector1 := pwrkVector1^;
     pwrkVector2 := Model [i * 3];
     wrkVector2 := pwrkVector2^;
     pwrkVector3 := Model [i * 3 + 2];
     wrkVector3 := pwrkVector3^;

     vx1 := wrkVector1.X - wrkVector2.X;
     vy1 := wrkVector1.Y - wrkVector2.Y;
     vz1 := wrkVector1.Z - wrkVector2.Z;

     vx2 := wrkVector2.X - wrkVector3.X;
     vy2 := wrkVector2.Y - wrkVector3.Y;
     vz2 := wrkVector2.Z - wrkVector3.Z;

     nx := vy1 * vz2 - vz1 * vy2;
     ny := vz1 * vx2 - vx1 * vz2;
     nz := vx1 * vy2 - vy1 * vx2;

     wrki := sqrt (nx * nx + ny * ny + nz * nz);
     if wrki = 0 then wrki := 1;

     wrkVector.X := nx / wrki;
     wrkVector.Y := ny / wrki;
     wrkVector.Z := nz / wrki;

     New (pwrkVector);
     pwrkVector^ := wrkVector;

     Normals.Add (pwrkVector);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
  t : TextFile;
  p : ^TD3DVector;
  n : ^TD3DVector;
begin
  if OpenDialog1.Execute then begin
  if SaveDialog1.Execute then begin
  Model := TList.Create;
  Normals := TList.Create;
  LoadDxf (OpenDialog1.FileName);
  CalcNormals;
  Caption := 'Треугольников - ' + IntToStr(Normals.Count);
  AssignFile (t, SaveDialog1.FileName);
  ReWrite (t);
  for i := 0 to Normals.Count - 1 do begin
      n := Normals.Items [i];
      WriteLn (t, n.X);
      WriteLn (t, n.Y);
      WriteLn (t, n.Z);

      p := Model.Items [i * 3];
      WriteLn (t, p.X);
      WriteLn (t, p.Y);
      WriteLn (t, p.Z);

      p := Model.Items [i * 3 + 1];
      WriteLn (t, p.X);
      WriteLn (t, p.Y);
      WriteLn (t, p.Z);

      p := Model.Items [i * 3 + 2];
      WriteLn (t, p.X);
      WriteLn (t, p.Y);
      WriteLn (t, p.Z);
  end;
  CloseFile (t);
  Model.Free;
  Normals.Free;
  end;
  end;
end;

end.
