{************************************************************}
{                   Delphi VCL Extensions                    }
{                                                            }
{                 Basic constants and types                  }
{                                                            }
{      Copyright (c) 2002-2004 SoftGold software company     }
{                                                            }
{************************************************************}
unit sgConsts;


interface

uses
  Windows;

// Constants
const
  Info_0 = 0;
  Text_1 = 1;
  Name_2 = 2;
  Text_3 = 3;
  Text_4 = 4;
  Text_5 = 5;
  LineTypeName_6 = 6;
  TextFont_7 = 7;
  LayerName_8 = 8;
  VarName_9 = 9;
  XFirst_10 = 10;
  XOther_11 = 11;
  XOther_12 = 12;
  XOther_13 = 13;
  XOther_14 = 14;
  XOther_15 = 15;
  XOther_16 = 16;
  XOther_17 = 17;
  XOther_18 = 18;
  YFirst_20 = 20;
  YOther_21 = 21;
  YOther_22 = 22;
  YOther_23 = 23;
  YOther_24 = 24;
  YOther_25 = 25;
  YOther_26 = 26;
  YOther_27 = 27;
  YOther_28 = 28;
  ZFirst_30 = 30;
  ZOther_31 = 31;
  ZOther_32 = 32;
  ZOther_33 = 33;
  ZOther_34 = 34;
  ZOther_35 = 35;
  ZOther_36 = 36;
  ZOther_37 = 37;
  Elevation_38 = 38;
  TableOfEntity_39 = 39;
  Float_40 = 40;
  Float_41 = 41;
  Float_42 = 42;
  Float_43 = 43;
  Float_44 = 44;
  Float_45 = 45;
  Float_46 = 46;
  Float_47 = 47;
  Float_48 = 48;
  FloatRepeated_49 = 49;
  Float_211 = 211;
  Float_221 = 221;
  Float_231 = 231;
  Angle_50 = 50;
  Angle_51 = 51;
  Angle_52 = 52;
  Angle_53 = 53;
  Angle_54 = 54;
  Angle_55 = 55;
  Angle_56 = 56;
  Angle_57 = 57;
  Angle_58 = 58;
  Visible_60 = 60;
  ColorNumber_62 = 62;
  EntitysBegin_66 = 66;
  PaperSpace_67 = 67;
  Integer_68 = 68;
  Integer_69 = 69;
  Integer_70 = 70;
  Integer_71 = 71;
  Integer_72 = 72;
  Integer_73 = 73;
  Integer_74 = 74;
  Integer_75 = 75;
  Integer_76 = 76;
  Integer_77 = 77;
  Integer_78 = 78;
  Integer_79 = 79;
  Integer_90 = 90;
  Integer_91 = 91;
  Integer_92 = 92;
  Integer_93 = 93;
  Integer_97 = 97;
  Integer_290 = 290;
  Integer_1070 = 1070;
  Extrusion_210 = 210;
  Extrusion_220 = 220;
  Extrusion_230 = 230;
  String_330 = 330;
  String_331 = 331;
  String_340 = 340;
  String_341 = 341;
  Integer_370 = 370;
  String_1000 = 1000;  
  String_1005 = 1005;
  Float_1040 = 1040;

  UserDigit = 23111;

  sModel  = 'Model';
  sLayout = 'Layout1';
  sACADXDataAppName = 'ACAD';
  sActiveVPort = '*ACTIVE';
  sModelSpace  = '*MODEL_SPACE';
  sPaperSpace  = '*PAPER_SPACE';

  sTextStyleStandardName = 'STANDARD';

  // Names of a DXF-entities
  sPolyline = 'Polyline';
  sCircle   = 'Circle';
  sEllipse  = 'Ellipse';
  sHatchEntity   = 'HATCH';
  sPatternSOLID  = 'SOLID';
  sPatternANSI31 = 'ANSI31';// FDiagonal, BDiagonal
  sPatternANSI37 = 'ANSI37';// DiagCross
  sPatternNET    = 'NET';   // Cross
  sPatternLINE   = 'LINE';  // Horizintal, Vertical

  // Default numbers of parts for parsing circle and spline
  iDefaultNumberOfCircleParts = 16;
  iDefaultNumberOfSplineParts = 25;

  //Maximum count of the lines in a dotted polyline or curve
  //(if count of lines more then iMaxNumDottedLines we draws solid-polyline)
  iMaxNumDottedLines = 1000;

  //It is necessary for comparison floating-point numbers
  fAccuracy = 0.000001;
  // bad value for all singles
  BadSingValue: Single = -24444444;


  sImpossiblePointerID  = '#';
  sFilledArrowForLeader = 'Filled_arrow_for_leader';
  sNewBlockID = '#NewBlockID';

// Types
type
  PFPoint = ^TFPoint;
  TFPoint = record
    X: single;
    Y: single;
    Z: single;
  end;

  PdxfPoint = ^TdxfPoint;
  TdxfPoint = record
    X,Y,Z: Single;
  end;

  TFRect = record
  case Integer of
    0: (Left, Top, Z1, Right, Bottom, Z2: Single);
    1: (TopLeft, BottomRight: TFPoint);
  end;

  PdxfData = ^TdxfData;
  TdxfData = packed record
    Tag: Word;       // classindex, DXF_LINE, DXF_SOLID etc.
    Count: Word;     // number of child entities
    TickCount: Word;
    Flags: Byte;     // Flags byte
		     // for polylines: low bit <> 0 - is closed
		     // for layers: low bit <> 0 - is invisible
    Style: Byte;     // Style (pen, brush...) - for future versions
    Dimension: Integer;
    DashDots: PdxfPoint;
    DashDotsCount: Integer;
    Color: Integer;  // Color of entity
    Ticks: Pointer;
    Thickness: Single;// for future versions
    Rotation: Single; // Text or block rotation angle
    Layer: PChar;  // Layer name (only one layer for element)
    Text:  PChar;  // Pointer to text string
    FontName: PChar;
    Handle: THandle;
    Unused: Integer;
    Point: TdxfPoint;   // Coordinates of the first point
    Point1: TdxfPoint;  // Coordinates of the second point
    Point2: TdxfPoint;  // Coordinates of the third point
    Point3: TdxfPoint;  // Coordinates of the fourth point
    case Integer of
    0: (Radius,StartAngle,EndAngle: Single);    // for arcs (NOT in DXFEnum)
    1: (Block: THandle; Scale: TdxfPoint);      // for Inserts (NOT in DXFEnum)
    2: (FHeight,FScale,RWidth,RHeight: Single; HAlign,VAlign: Byte);    // for Text
    3: (Points: PdxfPoint);                     // for polylines (in DXFEnum)
    //4: (Point2, Point3: TdxfPoint);
  end;

  // Axes in 3-Dimensional cartesian coordinates
  TsgAxes = (axisX, axisY, axisZ);

  TsgHatchStyle = (hsSolid, hsPatternData, hsHorizontal, hsVertical, hsFDiagonal,
                  hsBDiagonal, hsCross, hsDiagCross);

  TsgImportMode = (imView, imImport);

  TFMatrix = array[0..3,0..2] of Single;

function Degree(ARadian: Extended): Extended;
function ConvToFloatDef(const S: string; const Value: Extended): Extended;
function MakeFPoint(X, Y, Z: Single): TFPoint;
function MakeFRect(Left, Top, Z1, Right, Bottom, Z2: Single): TFRect;
function MakeFPointFromDXF(const AdxfPoint: TdxfPoint): TFPoint;
function IdentityMat: TFMatrix;
function IsRotated(const M: TFMatrix): Boolean;
//function MatFromExtr(const P: TFPoint; Angle: Single): TFMatrix;
procedure MatOffset(var M: TFMatrix; const P: TFPoint);
function MatXMat(const A,B: TFMatrix): TFMatrix;
function PtXMat(const P: TFPoint; const M: TFMatrix): TFPoint;
function Radian(Angle: Extended): Extended;
function StdMat(const S, P: TFPoint): TFMatrix;

implementation

uses Math, SysUtils, Graphics;

function ConvToFloatDef(const S: string; const Value: Extended): Extended;
begin
  if not TextToFloat(PChar(S), Result, fvExtended) then
    Result := Value;
end;

function MakeFPoint(X, Y, Z: Single): TFPoint;
begin
  Result.X := X;
  Result.Y := Y;
  Result.Z := Z;
end;

function MakeFRect(Left, Top, Z1, Right, Bottom, Z2: Single): TFRect;
begin
  Result.Left := Left;
  Result.Top := Top;
  Result.Z1 := Z1;
  Result.Right := Right;
  Result.Bottom := Bottom;
  Result.Z2 := Z2;
end;

function MakeFPointFromDXF(const AdxfPoint: TdxfPoint): TFPoint;
begin
  Result.X := AdxfPoint.X;
  Result.Y := AdxfPoint.Y;
  Result.Z := AdxfPoint.Z;
end;

function Radian(Angle: Extended): Extended;
begin
  Result := Angle * Pi / 180;
end;

function Degree(ARadian: Extended): Extended;
begin
  Result := ARadian * 180 / Pi;
end;

function PtXMat(const P: TFPoint; const M: TFMatrix): TFPoint;
  function Part(I: Integer): Extended;
  begin
    Result := P.X * M[0,I] + P.Y * M[1,I] + P.Z * M[2,I] + M[3,I];
  end;
begin
  Result.X := Part(0);
  Result.Y := Part(1);
  Result.Z := Part(2);
end;

function MatXMat(const A,B: TFMatrix): TFMatrix;
var
  I,J: Integer;
begin
  for I := 0 to 3 do
  begin
    for J := 0 to 2 do
      Result[I,J] := A[I,0] * B[0,J] + A[I,1] * B[1,J] + A[I,2] * B[2,J];
  end;
  for J := 0 to 2 do
    Result[3,J] := Result[3,J] + B[3,J];
end;

function IsRotated(const M: TFMatrix): Boolean;
var
  I,J: Integer;
begin
  Result := False;
  for I := 0 to 2 do
  begin
    for J := 0 to 2 do
    begin
      if I = J then
        Continue;
      Result := M[I,J] <> 0.0;
      if Result then
        Exit;
    end;
  end;
end;

procedure MatOffset(var M: TFMatrix; const P: TFPoint);
begin
  M[3,0] := P.X;
  M[3,1] := P.Y;
  M[3,2] := P.Z;
end;

function StdMat(const S,P: TFPoint): TFMatrix;
begin
  FillChar(Result, SizeOf(Result), 0);
  Result[0,0] := S.X;
  Result[1,1] := S.Y;
  Result[2,2] := S.Z;
  MatOffset(Result,P);
end;

function IdentityMat: TFMatrix;
begin
  FillChar(Result, SizeOf(Result), 0);
  Result[0,0] := 1;
  Result[1,1] := 1;
  Result[2,2] := 1;
end;

end.
