unit U_ExportDXF;

interface

uses windows, Dialogs, PowerCad, SysUtils, U_Cad, DrawObjects, Clipbrd, Classes, PCTypesUtils, Math, U_DXFEngineSCS,
     forms, ShellApi, tlhelp32, U_ESCadClasess, Graphics, fplan, rrEllipses;

  procedure SaveDXFFile(aPCad: TPowerCad; aTitle, aFilter: string; aDefExt: string = '*.dxf');
  procedure ExportCADAsDXF(aPCad: TPowerCad; aFileName: string);
  function AutoCorrectLayerName(aStr: string; num: integer): string;
  function AutoCorrectBlockName(aStr: string; num: integer): string;
  function GetFiguresByLayer(aPCad: TPowerCad; aLayer: TLayer; aLayerNbr: integer): TList;
  procedure AddFiguresToLayer(aDXFLayer: DXF_Layer; aFigures: TList; LayerNbr: integer);
  function ModificateFloat(aVal: Double): Double; //01.11.2012 - подгонка значений {TODO}
  function ModificatePoint(aP: Point3D): Point3D;
  function GetRealRichTextLinesCount(aRichText: TRichText): Integer;
  function GetDrawFigureWithoutDuplicates(aInFigures: TList): TList;

  //Tolik 14/03/2018--
  //function DxfTextCorrect(aText: string): string;
  function DxfTextCorrect(aText: string; AFontName: String = ''): string;
  //

  function CheckBlockNameExist(aName: string): string;

  // write enttities
  function Write_TLine(aObject: TLine; aZ: double = 0): DXF_Entity;
  function Write_TVertex(aObject: TVertex; aZ: double = 0): DXF_Entity;
  function Write_TRectangle(aObject: TRectangle; aZ: double = 0): DXF_Entity;
  function Write_TCircle(aObject: TCircle; aZ: double = 0): DXF_Entity;
  function Write_TPolyline(aObject: TPolyline; aZ: double = 0): DXF_Entity;
  function Write_TEllipse(aObject: TEllipse; aZ: double = 0): DXF_Entity;
  function Write_TArc(aObject: TArc; aZ: double = 0): DXF_Entity;
  function Write_TElpArc(aObject: TElpArc; aZ: double = 0): DXF_Entity;
  function Write_TText(aObject: TText; aZ: double = 0): DXF_Entity;
  function Write_TRichText(aObject: TRichText; aZ: double = 0): DXF_Entity;
  function Write_TWMFObject(aObject: TWMFObject; aZ: double = 0): DXF_Entity;
  function Write_TBMPObject(aObject: TBMPObject; aZ: double = 0): DXF_Entity;
  function Write_TBlock(aObject: TFigureGrp; aZ: double = 0; aLayerNbr: integer = 0): TList;

  function Write_THDimLine(aObject: THDimLine): TList;
  function Write_TVDimLine(aObject: TVDimLine): TList;
  function Write_TCabinet(aObject: TCabinet): TList;
  function Write_TCabinetExt(aObject: TCabinetExt): TList;
  function Write_TOrthoLine(aObject: TOrthoLine): TList;
  function Write_TConnectorObject(aObject: TConnectorObject): TList;
  function Write_TSCSFigureGrp(aObject: TSCSFigureGrp): TList;
  function Write_TNet(aObject: TNet): TList;
  function Write_TNetPath(aObject: TNetPath): TList;
  function Write_TNetDoor(aObject: TNetDoor): TList;
  function Write_TNetCol(aObject: TNetCol): DXF_Entity;

  function Write_TPlanObject(aObject: TPlanObject): TList;
  function Write_TPlanTrace(aObject: TPlanTrace): DXF_Entity;

  //function ColorToDxfColor(aColor: TColor): LongInt;//Integer;
  function ColorToDxfColor(aColor: TColor): Integer;
  //
                      
  function LineStyleToDxfLineStyle(aStyle: Integer): string;

const
  ModKoeff = 1; //10;

var
  LayersList: TList;
  GLayerNumber: integer;
  GaPCad: TPowerCad;
  FExportZ: Boolean;
  FKoefZ: Double;
  FBlocksNames: TStringList;
  DupIndex: integer;
  Rnd: integer = 4;
  NeedRnd: boolean = True;
  scalex: double = 0.45; // 0.5
  scaley: double = 1;
  scaleh: double = 1;
  scalehcr: double = 1;
  FLineTypeScale: Double = 400;
implementation

uses U_ProtectionCommon, USCS_Main, U_Common, PCDrawBox, U_BaseCommon, U_Constants, U_Layers,
  PCDrawing, Controls, RichEdit2, StdCtrls, {Tolik 10/07/2019 -- } IniFiles, {Tolik 01/08/2019 -- }U_BaseSettings;


procedure SaveDXFFile(aPCad: TPowerCad; aTitle, aFilter: string; aDefExt: string = '*.dxf');
var
  i: Integer;
  SaveDXF: TSaveDialog;
  mess: string;
  // Tolik 10/07/2019 --
  ini_file: TIniFile;
  function GetIniPath: String;
  begin
    {$if Defined(ES_GRAPH_SC)}
      Result := ExeDir + '\' + 'Scs.ini';
    {$else}
      Result := ExtractFilePath(paramstr(0)) + 'Scs.ini';
    {$ifend}
  end;
  //
begin
  SaveDXF := TSaveDialog.Create(nil);
  with SaveDXF do
  begin
    InitialDir := ExtractDirByCategoryType(dctDXF); //ExtractSaveDirForCategory('DXF');//GetEXEDir + '\DXF';
    Title := aTitle;
    Filter := aFilter;
    DefaultExt := '*.dxf';
    FileName := '';
    Options := [ofReadOnly,ofHideReadOnly,ofPathMustExist,ofFileMustExist] + [ofOverwritePrompt];
  end;
  if SaveDXF.Execute then
  begin
    // Tolik 01/08/2019 -- сохранить последний путь
    if GStoreLastPaths then
      WriteEnvironmentDir(dctDXF, ExtractFileDir(SaveDxf.FileName));
    //

    // Tolik -- 28/10/2016-- если файл еже есть и кем-то открыт -- хер что запишет, но закрывается без ошибок,/
    // поэтому нужна проверка
    if fileExists(SaveDxf.FileName) then
    begin
      // не смогли удалить - сообщение и нах отсюда 
      if not DeleteFile(SaveDXF.FileName) then
      begin
        ShowMessage(cMain_Mes8);
        exit;
      end;
    end;
    //
    try
      // Tolik 10/07/2019 --
        // определить настройки из иника для експорта ортолиний
        ini_file := nil;
        try
          ini_file := TIniFile.Create(GetIniPath);
        except
          on E: Exception do
            AddExceptionToLog('LoadDxfFile Error Reading SCS.ini file', false);
        end;
        if ini_file <> nil then
        begin
          if ini_file.SectionExists('ExportDXF') then
          begin
            FLineTypeScale := Ini_File.ReadInteger('ExportDXF', 'LineTypeScale', 400);
            ini_file.Free;
          end;
        end;
      //
      if pos('.wmf', AnsiLowerCase(SaveDXF.FileName)) <> 0 then
      begin
        try
          aPCad.ExportAsWmf(SaveDXF.FileName);
        except
        end;
      end
      else
      begin
        BeginProgress;
        try
          mess := cExportDXF_Mes2;
          //if MessageBox(FSCS_Main.Handle, PAnsiChar(mess), cExportDXF_Mes1, MB_YESNO) = IDYes then
          //if MessageBoxA(FSCS_Main.Handle, PAnsiChar(mess), cExportDXF_Mes1, MB_YESNO) = IDYes then
          if MessageBox(FSCS_Main.Handle, PChar(mess), PChar(cExportDXF_Mes1), MB_YESNO) = IDYes then
          begin
            FExportZ := True;
            FKoefZ := 1000 / GCadForm.PCad.MapScale;
          end
          else
          begin
            FExportZ := False;
            FKoefZ := 0;
          end;
          // экспортировать как дхф
          FBlocksNames := TStringList.Create;
          DupIndex := 0;
          ExportCADAsDXF(aPCad, SaveDXF.FileName);
          FreeAndNil(FBlocksNames);
        except
          on E: Exception do AddExceptionToLogEx('U_ExportDXF.SaveDXFFile', E.Message);
        end;
        EndProgress;
      end;
    except
      on E: Exception do AddExceptionToLogEx('U_ExportDXF.SaveDXFFile', E.Message);
    end;
  end;
  FreeAndNil(SaveDXF);
end;

function ConvertDXFToDWG(aDXFFileName: string): string;
var
  ProgStr: string;
  ParamStr: string;
  fromDir, outDir: string;
  SCSTmpDir: string;

  c1: Cardinal;
  pe: TProcessEntry32;
  s1: string;
  x: integer;
  FContinue: boolean;
begin
  try
    Result := '';
    ProgStr := GetEXEDir + '\DWG\DWG.exe';
    SCSTmpDir := GetPathToSCSTmpDir;
    if DirectoryExists(SCSTmpDir + '\DWG') then
      FullRemoveDir(SCSTmpDir + '\DWG', true, true);
    CreateDir(SCSTmpDir + '\DWG');
    CreateDir(SCSTmpDir + '\DWG\OUT');
    fromDir := SCSTmpDir + '\DWG';
    outDir := SCSTmpDir + '\DWG\OUT';
    CopyFile(PChar(aDXFFileName), PChar(fromDir + '\temp.dwg'), False);
    ParamStr := fromDir + ' ' + outDir + ' ' + '"ACAD2004" "DWG" "0" "0"';
    ShellExecute(FSCS_Main.Handle, 0, PChar(ProgStr), PChar(ParamStr), 0, SW_HIDE);
    Result := outDir + '\temp.dwg';

    repeat
    X := 0;
    FContinue := True;
    c1 := CreateToolHelp32Snapshot(TH32CS_SnapProcess, 0);
    try
      pe.dwSize := sizeof(pe);
      if Process32First(c1, pe) then
      repeat
        s1 := ExtractFileName(pe.szExeFile);
        if s1 = 'DWG.exe' then
        begin
          inc(x);
          FContinue := False;
        end;
      until not Process32Next(c1, pe);
    finally
      CloseHandle(c1);
    end;
    until FContinue;

    CopyFile(PChar(outDir + '\temp.dwg'), PChar(aDXFFileName), False);

  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.ConvertDXFToDWG', E.Message);
  end;
end;

procedure ExportCADAsDXF(aPCad: TPowerCad; aFileName: string);
var
  i, j, k: Integer;
  DXFObj: DXF_ObjectSCS;
  DXFLayer: DXF_Layer;
  Layer: TLayer;
  FigList: TList;
  count: integer;
  eList: Entity_List;
  Entity: DXF_Entity;
  DWGFileName: string;
  // Tolik - - 17/02/2017 --
  RefreshCadFlag: Boolean;

  function  CheckRenameLayer(aName: String):String;
  var i: Integer;
      LayerNameExists: Boolean;
  begin
    LayerNameExists := false;
    Result := aName;
    for i := 0 to LayersList.Count - 1 do
    begin
      if DXF_Layer(LayersList[i]).name = Result then
      begin
        LayerNameExists := True;
        Result :=  Result + '1';
      end;
    end;
    if LayerNameExists then
        Result := CheckRenameLayer(Result);
  end;
  //
begin
  RefreshCadFlag := GCanRefreshCad;
  GCanRefreshCad := False;
  try
    // Tolik -- 08/02/2017 --
    FigList := nil;
    DXFObj := nil;
    //
    GaPCad := aPCad;
    DXFObj := DXF_ObjectSCS.create(aFileName);
    LayersList := TList.Create;
    for i := 1 to aPCad.LayerCount - 1 do
    begin
      Layer := TLayer(aPCad.Layers[i]);

      //FigList := GetFiguresByLayer(aPCad, Layer);
      // Tolik -- 16/02/2017 --
      // DXFLayer := DXF_Layer.create(AutoCorrectLayerName(Layer.name, i));
      DXFLayer := DXF_Layer.create(CheckRenameLayer(AutoCorrectLayerName(Layer.name, i)));
      //

      DXFLayer.SCS_Layer_Handle := Integer(Layer);
      DXFLayer.layer_colinx := 7;
      LayersList.Add(DXFLayer);
      //AddFiguresToLayer(DXFLayer, FigList);
      //DXFObj.add_layer(DXFLayer);
    end;
    for i := 1 to aPCad.LayerCount - 1 do
    begin
      Layer := TLayer(aPCad.Layers[i]);
      FigList := GetFiguresByLayer(aPCad, Layer, i);
      // Tolik -- 15/02/2017 --
      if FigList.count > 0 then
      begin
        //
        DXFLayer := DXF_Layer(LayersList[i - 1]);
        AddFiguresToLayer(DXFLayer, FigList, 0{i});
      end;
      //
      // Tolik 08/02/2017 --
       if FigList <> nil then
         FreeAndNil(FigList);
      //
    end;
    for i := 1 to aPCad.LayerCount - 1 do
    begin
      DXFLayer := DXF_Layer(LayersList[i - 1]);
      DXFObj.add_layer(DXFLayer);
    end;
    DXFObj.save_to_file(aFileName);
    try
      LayersList.Free;
    except
    end;
    if ansilowercase(ExtractFileExt(aFileName)) = '.dwg' then
      DWGFileName := ConvertDXFToDWG(aFileName);

  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.ExportCADAsDXF', E.Message);
  end;
  // Tolik -- 08/02/2017 --
  if FigList <> nil then
    FreeAndNil(FigList);
  if DXFObj <> nil then
    FreeAndNil(DXFObj);

  GCanRefreshCad := RefreshCadFlag;
end;

function AutoCorrectLayerName(aStr: string; num: integer): string;
var
  i: integer;
begin
  try
    for i := 0 to Length(aStr) - 1 do
    begin
      if aStr[i] = ' ' then
        aStr[i] := '_';
      if aStr[i] = '&' then
        aStr[i] := '_';
      if aStr[i] = '@' then
        aStr[i] := '_';
      if aStr[i] = '.' then
        aStr[i] := '_';
      if aStr[i] = '(' then
        aStr[i] := '_';
      if aStr[i] = ')' then
        aStr[i] := '_';
    end;
    Result := aStr;
    if length(Result) > 30 then
      Result := copy(Result, 1, 26) + inttostr(num);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.AutoCorrectLayerName', E.Message);
  end;
end;

function AutoCorrectBlockName(aStr: string; num: integer): string;
var
  i: integer;
begin
  try
    for i := 0 to Length(aStr) - 1 do
    begin
      if aStr[i] = ' ' then
        aStr[i] := '_';
      if aStr[i] = '.' then
        aStr[i] := '_';
      if aStr[i] = '(' then
        aStr[i] := '_';
      if aStr[i] = ')' then
        aStr[i] := '_';
      if aStr[i] = '@' then
        aStr[i] := '_';
      if aStr[i] = '&' then
        aStr[i] := '_';
    end;
    Result := aStr;
    if length(Result) > 30 then
      Result := copy(Result, 1, 26) + inttostr(num);
    if length(Result) > 30 then
      Result := copy(Result, 1, 30);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.AutoCorrectBlockName', E.Message);
  end;
end;

function GetFiguresByLayer(aPCad: TPowerCad; aLayer: TLayer; aLayerNbr: integer): TList;
var
  i, j: integer;
  LHandle: Integer;
  vFigure: TFigure;
  vFigureIn: TFigure;
  
begin
  try
    Result := TList.Create;
    LHandle := Integer(aLayer);
    // &&&
    if aLayer.visible <> lost then
    begin
      if (aLayer.IsDxf) then // в слои которые от ДХФ собираем внутренности блока/ов которые на слое подложка
      // сами блоки не добавляем
      begin
        for i := 0 to aPCad.FigureCount - 1 do
        begin
          vFigure := TFigure(aPCad.Figures[i]);
          if (vFigure.LayerHandle = DXF_Layer(LayersList[0]).SCS_Layer_Handle) then
          begin
            if (vFigure.ClassName = 'TFigureGrp') or (vFigure.ClassName = 'TBlock') then
            begin
              for j := 0 to TFigureGrp(vFigure).InFigures.Count - 1 do
              begin
                vFigureIn := TFigure(TFigureGrp(vFigure).inFigures[j]);
                if vFigureIn.LayerHandle = LHandle then
                  Result.Add(vFigureIn);
              end;
            end;
          end
          else
          begin
            if vFigure.LayerHandle = LHandle then
              Result.Add(vFigure);
          end;
        end;
      end
      else
      begin
        if (aLayerNbr = 1) then  // со слоя подложка собираем только фигуры вне блоков, или которые
        // в блоках внутри но сами тоже на слое подложка, сами блоки не добавляем
        begin
          for i := 0 to aPCad.FigureCount - 1 do
          begin
            vFigure := TFigure(aPCad.Figures[i]);
            if (vFigure.ClassName = 'TFigureGrp') or (vFigure.ClassName = 'TBlock') then
            begin
              if (vFigure.LayerHandle = LHandle) then
              begin
                for j := 0 to TFigureGrp(vFigure).InFigures.Count - 1 do
                begin
                  vFigureIn := TFigure(TFigureGrp(vFigure).inFigures[j]);
                  if vFigureIn.LayerHandle = LHandle then
                    Result.Add(vFigureIn);
                end;
              end;
            end
            else
            begin
              if vFigure.LayerHandle = LHandle then
                Result.Add(vFigure);
            end;
          end;
        end
        else
        begin
          for i := 0 to aPCad.FigureCount - 1 do
          begin
            vFigure := TFigure(aPCad.Figures[i]);
            if vFigure.LayerHandle = LHandle then
              Result.Add(vFigure);
          end;
        end;
      end;
    end;

  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.GetFiguresByLayer', E.Message);
  end;
end;

function Round3My(Num: Extended): Extended;//Extended;
begin
  If NeedRnd then
  begin
    result := RoundN(Num, Rnd);
  end
  else
    Result := Num;
end;

function ModificateFloat(aVal: Double): Double;
var
  MapScale: Double;
begin
  //Result := aVal;
  //Result := aVal * ModKoeff;
  //Result := aVal * MapScale;

  //MapScale := Round3My(GCadForm.PCad.MapScale);
  MapScale := GCadForm.PCad.MapScale;
  Result := Round3My(aVal * MapScale);
end;

function ModificatePoint(aP: Point3D): Point3D;
var
  xx, yy, CadHeight, CadWidth: double;
  MapScale: Double;
begin
  try
    {//01.11.2012
    result := aPoint3D(aP.x, aP.y, aP.z);
    // наша
    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      CadHeight := GCadForm.PCad.WorkHeight;
      result.y := CadHeight - Result.y;
    end;
    // хз
    if ord(GCadForm.PCad.HorizontalZero) = 1 then
    begin
      CadWidth := GCadForm.PCad.WorkWidth;
      result.x := CadWidth - Result.x;
    end;{}

    { test
    result := aPoint3D(aP.x * ModKoeff, aP.y * ModKoeff, aP.z * ModKoeff);
    // наша
    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      CadHeight := GCadForm.PCad.WorkHeight * ModKoeff;
      result.y := CadHeight - Result.y;
    end;
    // хз
    if ord(GCadForm.PCad.HorizontalZero) = 1 then
    begin
      CadWidth := GCadForm.PCad.WorkWidth * ModKoeff;
      result.x := CadWidth - Result.x;
    end; {}

    //MapScale := Round3My(GCadForm.PCad.MapScale);
    MapScale := GCadForm.PCad.MapScale;


    {Рабочий код с MapScale
    result := aPoint3D(aP.x * MapScale, aP.y * MapScale, aP.z * MapScale);
    // наша
    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      CadHeight := GCadForm.PCad.WorkHeight * MapScale;
      result.y := CadHeight - Result.y;
    end;
    // хз
    if ord(GCadForm.PCad.HorizontalZero) = 1 then
    begin
      CadWidth := GCadForm.PCad.WorkWidth * MapScale;
      result.x := CadWidth - Result.x;
    end;}

    (*
    result := aPoint3D(Round3My(aP.x * MapScale), Round3My(aP.y * MapScale), Round3My(aP.z * MapScale));
    // наша
    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      CadHeight := Round3My(GCadForm.PCad.WorkHeight * MapScale);
      result.y := CadHeight - Result.y;
    end;
    // хз
    if ord(GCadForm.PCad.HorizontalZero) = 1 then
    begin
      CadWidth := Round3My(GCadForm.PCad.WorkWidth * MapScale);
      result.x := CadWidth - Result.x;
    end;
    *)
    // наша
    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      CadHeight := GCadForm.PCad.WorkHeight;
      yy := RoundN(Round3My(CadHeight - aP.y) * MapScale, 2);
    end
    else
      yy := RoundN(Round3My(aP.y) * MapScale, 2);
    // хз
    if ord(GCadForm.PCad.HorizontalZero) = 1 then
    begin
      CadWidth := GCadForm.PCad.WorkWidth;
      xx := RoundN(Round3My(CadWidth - aP.x) * MapScale, 2);
    end
    else
      xx := RoundN(Round3My(aP.x) * MapScale, 2);
    result := aPoint3D(xx, yy, RoundN(aP.z * MapScale, 2));
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.ModificatePoint', E.Message);
  end;
end;

function GetRealRichTextLinesCount(aRichText: TRichText): Integer;
var
  i: integer;
begin
  try
    Result := 0;
    for i := 0 to aRichText.re.Lines.Count - 1 do
    begin
      if aRichText.re.Lines[i] <> '' then
        Result := Result + 1;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.GetRealRichTextLinesCount', E.Message);
  end;
end;

function GetDrawFigureWithoutDuplicates(aInFigures: TList): TList;
var
  i, j: Integer;
  InFigure: TFigureGrpMod;
  Exist: Boolean;
begin
  try
    Result := TList.create;
    for i := 0 to aInFigures.Count - 1 do
    begin
      InFigure := TFigureGrpMod(aInFigures[i]);
      // Check
      Exist := false;
      for j := i -1 downto 0 do
      begin
        if TFigureGrpMod(aInFigures[j]).Name = InFigure.Name then
          exist := true;
      end;
      if not exist then
        Result.Add(InFigure);
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.GetDrawFigureWithoutDuplicates', E.Message);
  end;
end;

function CheckBlockNameExist(aName: string): string;
var
  i: Integer;
  r: integer;
begin
  try
    Result := aName;
    for i := 0 to FBlocksNames.Count - 1 do
    begin
      if aName = FBlocksNames.Strings[i] then
      begin
        inc(DupIndex);
        Result := 'DuplicatedBlock_' + IntToStr(DupIndex);
        break;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.CheckBlockNameExist', E.Message);
  end;
end;

function LineStyleToDxfLineStyle(aStyle: Integer): string;
begin
  try
    Result := '';
    if aStyle = ord(psSolid) then
      Result := 'SOLID';
    if aStyle = ord(psDash) then
      Result := 'DASH';
    if aStyle = ord(psDot) then
      Result := 'DOT';
    if aStyle = ord(psDashDot) then
      Result := 'DASHDOT';
    if aStyle = ord(psDashDotDot) then
      Result := 'DASHDOTDOT';
    if aStyle = ord(psClear) then
      Result := 'CLEAR';
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.LineStyleToDxfLineStyle', E.Message);
  end;
end;

function DxfTextCorrect(aText: string; aFontName: String = ''): string;
var
 i: integer;
begin
  try
    for i := 1 to Length(aText) do
    begin
      if (aText[i] = 'І') then
        aText[i] := 'I'
      else
      if (aText[i] = 'і') then
        aText[i] := 'i'
      // Tolik 14/03/2018 --
      else
      if (aText[i] = '№') then
        aText[i] := 'N'
      else  
      if aFontName = 'GOST' then
        if aText[i] = '#' then
          aText[i] := 'N';  
      //
    end;
    Result := aText;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.DxfTextCorrect', E.Message);
  end;
end;

// ********* WRITE ENTITIES **************
// ЛИНИЯ
function Write_TLine(aObject: TLine; aZ: double = 0): DXF_Entity;
var
  p1, p2: Point3D;
  style: string;
begin
  try
    Result := nil;
    p1 := aPoint3D(aObject.actualPoints[1].x, aObject.actualPoints[1].y, aZ);
    p2 := aPoint3D(aObject.actualPoints[2].x, aObject.actualPoints[2].y, aZ);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    style := LineStyleToDxfLineStyle(aObject.Style);
    if (style <> '') and (style <> 'CLEAR') then
    begin
      Result := Line_.create(p1, p2, aObject.color);
      LINE_(Result).fLineStyle := style;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TLine', E.Message);
  end;
end;

// ТОЧКА
function Write_TVertex(aObject: TVertex; aZ: double = 0): DXF_Entity;
var
  OCS_Z: Point3D;
  p1: Point3D;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    p1 := aPoint3D(aObject.ap1.x, aObject.ap1.y, aZ);
    p1 := ModificatePoint(p1);
    Result := Point_.create(OCS_Z, p1, aObject.color);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TVertex', E.Message);
  end;
end;

// ПРЯМОУГОЛЬНИК
function Write_TRectangle(aObject: TRectangle; aZ: double = 0): DXF_Entity;
var
  OCS_Z: Point3D;
  points: array[0..3] of Point3D;
  style: string;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    points[0] := aPoint3D(aObject.ap1.x, aObject.ap1.y, aZ);
    points[1] := aPoint3D(aObject.ap2.x, aObject.ap2.y, aZ);
    points[2] := aPoint3D(aObject.ap3.x, aObject.ap3.y, aZ);
    points[3] := aPoint3D(aObject.ap4.x, aObject.ap4.y, aZ);
    points[0] := ModificatePoint(points[0]);
    points[1] := ModificatePoint(points[1]);
    points[2] := ModificatePoint(points[2]);
    points[3] := ModificatePoint(points[3]);
    style := LineStyleToDxfLineStyle(aObject.Style);
    if (style <> '') and (style <> 'CLEAR') then
    begin
      Result := Polyline_.create(OCS_Z, 4, @points[0], aObject.color, true);
      Polyline_(Result).fLineStyle := style;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TRectangle', E.Message);
  end;
end;

// ОКРУЖНОСТЬ
function Write_TCircle(aObject: TCircle; aZ: double = 0): DXF_Entity;
var
  OCS_Z: Point3D;
  p1: Point3D;
  rad: double;
  style: string;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    p1 := aPoint3D(aObject.ap1.x, aObject.ap1.y, aZ);
    rad := ModificateFloat(aObject.Radius);
    p1 := ModificatePoint(p1);
    style := LineStyleToDxfLineStyle(aObject.Style);
    if (style <> '') and (style <> 'CLEAR') then
    begin
      Result := Circle_.create(OCS_Z, p1, rad, aObject.color);
      Circle_(Result).fLineStyle := style;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TCircle', E.Message);
  end;
end;

// ПОЛИЛИНИЯ
function Write_TPolyline(aObject: TPolyline; aZ: double = 0): DXF_Entity;
var
  i: integer;
  OCS_Z: Point3D;
  points: array of Point3D;
  style: string;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    SetLength(points, aObject.PointCount);
    for i := 0 to aObject.PointCount - 1 do
    begin
      points[i] := aPoint3D(aObject.ActualPoints[i + 1].x, aObject.ActualPoints[i + 1].y, aZ);
      points[i] := ModificatePoint(points[i]);
    end;
    style := LineStyleToDxfLineStyle(aObject.Style);
    if (style <> '') and (style <> 'CLEAR') then
    begin
      Result := Polyline_.create(OCS_Z, aObject.PointCount, @points[0], aObject.color, aObject.Closed);
      Polyline_(Result).fLineStyle := style;
    end;
    // Tolik -- 10/02/2017 --
    SetLength(points, 0);
    //
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TPolyline', E.Message);
  end;
end;

// ЭЛЛИПС
function Write_TEllipse(aObject: TEllipse; aZ: double = 0): DXF_Entity;
var
  Poly: TPolyline;
begin
  try
    Result := nil;
    DxfMode := True;
    Poly := TPolyline(aObject.DuplicateAsBezier);
    Result := Write_TPolyline(Poly, aZ);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TEllipse', E.Message);
  end;
  DxfMode := false;  
end;

// ДУГА
function Write_TArc(aObject: TArc; aZ: double = 0): DXF_Entity;
var
  OCS_Z: Point3D;
  p1: point3D;
  ta, rad, angle1, angle2: double;
  style: string;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    p1 := aPoint3D(aObject.ap1.x, aObject.ap1.y, aZ);
    rad := ModificateFloat(aObject.Radius);
    angle1 := aObject.SAngle * 180 / pi;
    angle2 := aObject.FAngle * 180 / pi;
    p1 := ModificatePoint(p1);

    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      if ord(GCadForm.PCad.HorizontalZero) = 0 then
      begin
        angle1 := 2 * pi - angle1;
        angle2 := 2 * pi - angle2;
        ta := angle1;
        angle1 := angle2;
        angle2 := ta;
      end;
    end;
    style := LineStyleToDxfLineStyle(aObject.Style);
    if (style <> '') and (style <> 'CLEAR') then
    begin
      Result := Arc_.create(OCS_Z, p1, rad, angle1, angle2, aObject.color);
      Arc_(Result).fLineStyle := style;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TArc', E.Message);
  end;
end;

// ЭЛЛИПС ДУГА
function Write_TElpArc(aObject: TElpArc; aZ: double = 0): DXF_Entity;
var
  Poly: TPolyline;
begin
  try
    Result := nil;
    DxfMode := True;
    Poly := TPolyline(aObject.DuplicateAsBezier);
    Result := Write_TPolyline(Poly, aZ);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TElpArc', E.Message);
  end;
  DxfMode := False;  
end;

// ТЕКСТ
function Write_TText(aObject: TText; aZ: double = 0): DXF_Entity;
var
  OCS_Z, p1, p2: point3D;
  strtext: string;
  height: double;
  hor_align: integer;
  a1, ta: double;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    //01.11.2012 p1 := aPoint3D(aObject.CenterPoint.x, aObject.CenterPoint.y, aZ);
    //05.11.2012 p1 := aPoint3D(aObject.CenterPoint.x-2, aObject.CenterPoint.y+6, aZ);
    p1 := aPoint3D(aObject.ap1.x, aObject.CenterPoint.y + aObject.Height / 2 , aZ);
    p2 := aPoint3D(0, 0, 1);
    strtext := DxfTextCorrect(aObject.Text, UpperCase(aObject.Font.Name));
    height := ModificateFloat(aObject.Height);
    hor_align := 0;
    p1 := ModificatePoint(p1);
    Result := Text_.create(OCS_Z, p1, p2, strtext, height, aObject.Font.Color, hor_align);
    // задать угол поворота
    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      if ord(GCadForm.PCad.HorizontalZero) = 0 then
      begin
        a1 := aObject.Angle;
        a1 := 2 * pi - a1;
      end;
    end;
    Text_(Result).angle := RadToDeg(a1);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Wtite_TText', E.Message);
  end;
end;

// ТЕКСТ RTF
function Write_TRichText(aObject: TRichText; aZ: double = 0): DXF_Entity;
var
  i: integer;
  Entity: DXF_Entity;
  OCS_Z, rtp1, p1, p2, tp1: point3D;
  rta1, rta2: TDoublePoint;
  strtext: string;
  rth, rtw: double;
  //txth: double;
  hor_align: integer;
  align_index: integer;
  ToBlock: TList;
  a1: double;
  LCount: Integer;
  //
  xCanvas: TMetafileCanvas;
  TM: TTextMetric;
  rtexth, w, h: double;
  delta: double;
  ww, hh: double;
  curry: double;
  tmptext: string;
  fSize: double;
  str_name: string;
  tmpStr: string;
  procWW: boolean;
  inc_ww_cnt: integer; 
begin
  // Tolik 08/02/2017 --    
  ToBlock := nil;          
  //       
  try
    
    tmpStr := aObject.re.Lines.Text;
    inc_ww_cnt := 0;
    procWW := true;
    
    ww := GetLineLenght(aObject.ap1, aObject.ap2);
    hh := GetLineLenght(aObject.ap1, aObject.ap4);
    //hh := round(hh * 4) + 5; // 1
    //ww := round(ww * 4) + 5; // 1
    hh := round(hh * 4) + 5; // 1
    ww := round(ww * 4) + 4; // 1
    while procWW do
    begin
      ww := ww + 1; 
      inc_ww_cnt := inc_ww_cnt + 1;
      aObject.re.Width := trunc(ww);
      aObject.re.Height := trunc(hh);
      aObject.re.Show;
      for i := 1 to 100 do
        Application.ProcessMessages;
      aObject.re.Hide;
      if tmpStr = aObject.re.Lines.Text then
        procWW := false
      else
      begin  
        if inc_ww_cnt > 20 then
        begin
          procWW := false;
          aObject.re.Lines.Text := tmpStr;
          aObject.re.Show;
          for i := 1 to 100 do
            Application.ProcessMessages;
          aObject.re.Hide;
          break;
        end;
      end;
    end;

    if aObject.re.Lines.Count = 1 then
      if Trim(aObject.re.Lines[0]) = '' then
        exit;   

    Result := nil;
    rtp1 := aPoint3D(aObject.CenterPoint.x, aObject.CenterPoint.y, aZ);
    rta1 := DoublePoint(aObject.ap1.x, aObject.ap1.y);
    rta2 := DoublePoint(aObject.ap2.x, aObject.ap2.y);

    OCS_Z := aPoint3D(0, 0, 1);
    p2 := aPoint3D(0, 0, 1);

    rtw := SQRT(SQR(aObject.ap1.x - aObject.ap2.x) + SQR(aObject.ap1.y - aObject.ap2.y));
    rth := SQRT(SQR(aObject.ap1.x - aObject.ap4.x) + SQR(aObject.ap1.y - aObject.ap4.y));
    // 06.11.2012
    //if aObject.re.Lines.Count > 1 then
      rtp1.y := rtp1.y - rth / 2;

    hor_align := 0;

    // 06.11.2012
    LCount := aObject.re.Lines.Count;
    //txth := rth  / LCount;
    ToBlock := TList.Create;
    {
    LCount := GetRealRichTextLinesCount(aObject);
    txth := rth  / LCount;
    ToBlock := TList.Create;
    }

    // РАЗОБРАТЬСЯ С РАСЧЕТАМИ !!!
(*
    txth := txth / 2;
    for i := 0 to LCount - 1 do
    begin
      strtext := aObject.re.Lines[i];
      tp1.x := rtp1.x - rtw / 2;
      tp1.y := rtp1.y - rth / 4 + txth + (txth * i);
      tp1.z := 0;
      tp1 := ModificatePoint(tp1);
      Entity := Text_.create(OCS_Z, tp1, p2, strtext, txth, aObject.color, hor_align);
      ToBlock.Add(Entity);
    end;
*)
    // ПОЛУЧИТЬ СВОЙСТВА
    tmptext := '';
    if trim(aObject.re.Lines.Text) <> '' then
    begin
      aObject.re.SelStart := 0;
      aObject.re.SelLength := 1;
      tmptext := aObject.re.SelText;
    end;

    // Tolik
    aObject.ttMetaFile:= TMetaFile.Create;
    aObject.ttMetafile.Enhanced := True;

    if length(tmptext) = 1 then
    begin
      xCanvas := TMetafileCanvas.Create(aObject.ttMetafile, 0);
      xCanvas.Font.Name := aObject.re.SelAttributes.Name;
      xCanvas.Font.Size := aObject.re.SelAttributes.Size;
      xCanvas.Font.Style := aObject.re.SelAttributes.Style;
    end
    else
    begin
      xCanvas := TMetafileCanvas.Create(aObject.ttMetafile, 0);
      xCanvas.Font.Name := aObject.re.Font.Name;
      xCanvas.Font.Size := aObject.re.Font.Size;
      xCanvas.Font.Style := aObject.re.Font.Style;
    end;
    GetTextMetrics(xCanvas.Handle, TM);

    fSize := xCanvas.Font.Size;
    rtp1.y := rtp1.y + 0.2 + xCanvas.Font.Size / 20;
      
    //h := TM.tmHeight / 4;
    h := TM.tmHeight / 4 - TM.tmDescent / 4;

    scalex := scalex;
    scaley := scaley;
    scaleh := scaleh;
    scalehcr := scalehcr;


    h := h * scaleh;

    rtexth := h * LCount + 1;
    delta := rth - rtexth - 1;
    w := 0;
    for i := 0 to LCount - 1 do
    begin
      if w < xCanvas.TextWidth(aObject.Re.Lines[i]) then
        w := xCanvas.TextWidth(aObject.Re.Lines[i]);
    end;
    w := (w + 3) / 4 ;
    FreeAndNil(xCanvas);
    aObject.ttMetaFile.Free;
    //if aObject.re.Lines.Count > 1 then
      curry := rtp1.y - h/6; // h/2
    for i := 0 to LCount - 1 do
    begin
      strtext := DxfTextCorrect(aObject.re.Lines[i], UPPERCASE(aObject.re.Font.Name));

      //tp1.x := rtp1.x - rtw / 2;
      //if aObject.re.Lines.Count > 1 then
        //tp1.x := rtp1.x - rtw / 2 + TM.tmAveCharWidth / 8; // TODO
        tp1.x := rtp1.x - rtw / 2 + fSize / 30; // TODO
      //else
      //  tp1.x := rtp1.x - rtw / 2;

      //tp1.y := rtp1.y + (h + delta) + (h * i) - (rth - 1) / 2;
      //if aObject.re.Lines.Count > 1 then
      //begin
        curry := curry + h + h/6; // h/2
        tp1.y := curry;
      //end
      //else
      //begin
        //tp1.y := rtp1.y + rth/2;
      //  tp1.y := rtp1.y + (h + delta) + (h * i) - (rth - 1) / 2;
      //end;

      tp1.z := aZ;
      tp1 := ModificatePoint(tp1);

      //01.11.2012 Entity := Text_.create(OCS_Z, tp1, p2, strtext, h, aObject.re.SelAttributes.Color, hor_align);
      //Entity := Text_.create(OCS_Z, tp1, p2, strtext, ModificateFloat(h), aObject.re.SelAttributes.Color, hor_align);
      Entity := Text_.create(OCS_Z, tp1, p2, strtext, ModificateFloat(h * scalehcr), aObject.re.SelAttributes.Color, hor_align);
      //Text_(Entity).ScaleX := 0.5;
      Text_(Entity).ScaleX := scalex;
      Text_(Entity).Scale.y := scaley;
      ToBlock.Add(Entity);
    end;

    rtp1 := aPoint3D(aObject.CenterPoint.x, aObject.CenterPoint.y, aZ);

    rtp1 := ModificatePoint(rtp1);

    str_name := AutoCorrectBlockName(aObject.Name, aObject.ID);
    str_name := CheckBlockNameExist(str_name{aObject.Name});
    Result := Block_.create(str_name{aObject.Name}, rtp1);
    FBlocksNames.Add(aObject.Name);
    for i := 0 to ToBlock.Count - 1 do
    begin
      Entity := DXF_Entity(ToBlock[i]);
      BLOCK_(Result).entities.Add(Entity);
    end;

    // задать угол поворота
    a1 := GetLineAngle(rta1, rta2);
    a1 := DegToRad(a1);
    if ord(GCadForm.PCad.VerticalZero) = 1 then
    begin
      if ord(GCadForm.PCad.HorizontalZero) = 0 then
      begin
        a1 := 2 * pi - a1;
      end;
    end;
    BLOCK_(Result).angle := RadToDeg(a1);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TRichText', E.Message);
  end;
  // Tolik -- 08/02/2017 --
  if ToBlock <> nil then
    FreeAndNil(ToBlock);
  //
end;

function Write_THDimLine(aObject: THDimLine): TList;
var
  p1, p2, p3: point3D;
  Entity: DXF_Entity;
  OCS_Z: point3D;
  strtext: string;
  height: double;
  hor_align: integer;
  
begin
  try
    Result := TList.Create;
    // 1
    p1 := aPoint3D(aObject.ap1.x, aObject.ap1.y, 0);
    p2 := aPoint3D(aObject.ap1.x, aObject.ap3.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, aObject.color);
    Result.Add(Entity);
    // 2
    p1 := aPoint3D(aObject.ap1.x, aObject.ap3.y, 0);
    p2 := aPoint3D(aObject.ap2.x, aObject.ap3.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, aObject.color);
    Result.Add(Entity);
    // 3
    p1 := aPoint3D(aObject.ap2.x, aObject.ap3.y, 0);
    p2 := aPoint3D(aObject.ap2.x, aObject.ap2.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, aObject.color);
    Result.Add(Entity);
    // text
    OCS_Z := aPoint3D(0, 0, 1);
    p2 := aPoint3D(0, 0, 1);
    strtext := aObject.caption;
    height := 3;
    hor_align := aObject.horzZero;
    p1.x := aObject.ap3.x;
    p1.y := aObject.ap3.y - height / 2;
    p1.z := 0;
    p1 := ModificatePoint(p1);
    Entity := Text_.create(OCS_Z, p1, p2, strtext, ModificateFloat(height), aObject.color, hor_align);
    Result.Add(Entity);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_THDimLine', E.Message);
  end;
end;

function Write_TVDimLine(aObject: TVDimLine): TList;
var
  p1, p2, p3: point3D;
  Entity: DXF_Entity;
  OCS_Z: point3D;
  strtext: string;
  height: double;
  hor_align: integer;
  a1: double;

begin
  try
    Result := TList.Create;
    // 1
    p1 := aPoint3D(aObject.ap1.x, aObject.ap1.y, 0);
    p2 := aPoint3D(aObject.ap3.x, aObject.ap1.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, aObject.color);
    Result.Add(Entity);
    // 2
    p1 := aPoint3D(aObject.ap3.x, aObject.ap1.y, 0);
    p2 := aPoint3D(aObject.ap3.x, aObject.ap2.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, aObject.color);
    Result.Add(Entity);
    // 3
    p1 := aPoint3D(aObject.ap3.x, aObject.ap2.y, 0);
    p2 := aPoint3D(aObject.ap2.x, aObject.ap2.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, aObject.color);
    Result.Add(Entity);
    // text
    OCS_Z := aPoint3D(0, 0, 1);
    p2 := aPoint3D(0, 0, 1);
    strtext := aObject.caption;
    height := 3;
    hor_align := aObject.horzZero;
    p1.x := aObject.ap3.x - height / 2;
    p1.y := aObject.ap3.y;
    p1.z := 0;
    p1 := ModificatePoint(p1);
    Entity := Text_.create(OCS_Z, p1, p2, strtext, ModificateFloat(height), aObject.color, hor_align);
    // задать угол поворота
    Text_(Entity).angle := 90;
    Result.Add(Entity);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TVDimLine', E.Message);
  end;
end;

function Write_TWMFObject(aObject: TWMFObject; aZ: double = 0): DXF_Entity;
var
  OCS_Z: Point3D;
  points: array[0..3] of Point3D;
  style: string;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    points[0] := aPoint3D(aObject.ap1.x, aObject.ap1.y, aZ);
    points[1] := aPoint3D(aObject.ap2.x, aObject.ap2.y, aZ);
    points[2] := aPoint3D(aObject.ap3.x, aObject.ap3.y, aZ);
    points[3] := aPoint3D(aObject.ap4.x, aObject.ap4.y, aZ);
    points[0] := ModificatePoint(points[0]);
    points[1] := ModificatePoint(points[1]);
    points[2] := ModificatePoint(points[2]);
    points[3] := ModificatePoint(points[3]);
    Result := Polyline_.create(OCS_Z, 4, @points[0], aObject.color, true);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TWMFObject', E.Message);
  end;
end;

function Write_TBMPObject(aObject: TBMPObject; aZ: double = 0): DXF_Entity;
var
  OCS_Z: Point3D;
  points: array[0..3] of Point3D;
  style: string;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    points[0] := aPoint3D(aObject.ap1.x, aObject.ap1.y, aZ);
    points[1] := aPoint3D(aObject.ap2.x, aObject.ap2.y, aZ);
    points[2] := aPoint3D(aObject.ap3.x, aObject.ap3.y, aZ);
    points[3] := aPoint3D(aObject.ap4.x, aObject.ap4.y, aZ);
    points[0] := ModificatePoint(points[0]);
    points[1] := ModificatePoint(points[1]);
    points[2] := ModificatePoint(points[2]);
    points[3] := ModificatePoint(points[3]);
    Result := Polyline_.create(OCS_Z, 4, @points[0], aObject.color, true);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TBMPObject', E.Message);
  end;
end;


function Write_TBlock(aObject: TFigureGrp; aZ: double = 0; aLayerNbr: integer = 0): TList;
var
  i, j: integer;
  BlkEntity, Entity, OutEntity: DXF_Entity;
  EntityList: TList;
  OutEntityList: TList;
  p1: point3D;
  ToBlock: TList;
  OutBlock: TList;
  vFigure: TFigure;
  str_name: string;
begin
  //Tolik -- 08/02/2017 --
  EntityList := nil;
  OutEntityList := nil;
  ToBlock := nil;
  OutBlock := nil;
  //
  try
    Result := TList.create;
    p1 := aPoint3D(aObject.CenterPoint.x, aObject.CenterPoint.y, aZ);

    ToBlock := TList.Create;
    OutBlock := TList.Create;

    // создавать все внутренние фигуры
    for i := 0 to aObject.InFigures.Count - 1 do
    begin
      // Tolik -- 08/02/2017 --
      Entity := nil;
      //EntityList := nil;
      OutEntity := nil;
      //OutEntityList := nil;
      //
      vFigure := TFigure(aObject.InFigures[i]);
      // Tolik -- 13/10/2017-- дописал везде ELSE, чтобы быстрее бегало без лишних проверок
      if vFigure.Visible then
      begin
        if vFigure.ClassName = 'TLine' then
          Entity := Write_TLine(TLine(vFigure), aZ)
        else
        if vFigure.ClassName = 'TVertex' then
          Entity := Write_TVertex(TVertex(vFigure), aZ)
        else
        if vFigure.ClassName = 'TRectangle' then
          Entity := Write_TRectangle(TRectangle(vFigure), aZ)
        else
        if vFigure.ClassName = 'TCircle' then
          Entity := Write_TCircle(TCircle(vFigure), aZ)
        else
        if vFigure.ClassName = 'TPolyline' then
          Entity := Write_TPolyline(TPolyline(vFigure), aZ)
        else
        if vFigure.ClassName = 'TEllipse' then
          Entity := Write_TEllipse(TEllipse(vFigure), aZ)
        else
        if vFigure.ClassName = 'TArc' then
          Entity := Write_TArc(TArc(vFigure), aZ)
        else
        if vFigure.ClassName = 'TElpArc' then
          Entity := Write_TElpArc(TElpArc(vFigure), aZ)
        else
        if vFigure.ClassName = 'TText' then
          Entity := Write_TText(TText(vFigure), aZ)
        else
        if (vFigure.ClassName = 'THDimLine') then
          EntityList := Write_THDimLine(THDimLine(vFigure))
        else
        if (vFigure.ClassName = 'TVDimLine') then
          EntityList := Write_TVDimLine(TVDimLine(vFigure))
        else

        if vFigure.ClassName = 'TWMFObject' then
          Entity := Write_TWMFObject(TWMFObject(vFigure), aZ)
        else
        if vFigure.ClassName = 'TBMPObject' then
          Entity := Write_TBMPObject(TBMPObject(vFigure), aZ)
        else

        // Out Of Block
        if (vFigure.ClassName = 'TRichText') or (vFigure.ClassName = 'TRichTextMod') or (vFigure.ClassName = 'TRichTextNotMod') then
          OutEntity := Write_TRichText(TRichText(vFigure), aZ)
        else
        if (vFigure.ClassName = 'TFigureGrp') or (vFigure.ClassName = 'TBlock') or
           (vFigure.ClassName = 'TFigureGrpMod') or (vFigure.ClassName = 'TFigureGrpNotMod') then
          OutEntityList := Write_TBlock(TFigureGrp(vFigure), aZ, aLayerNbr)
        else
        // TOrthoLine
        if (vFigure.ClassName = 'TOrthoLine') then
          EntityList := Write_TOrthoLine(TOrthoLine(vFigure))
        else
        // TConnectorObject
        if (vFigure.ClassName = 'TConnectorObject') then
          EntityList := Write_TConnectorObject(TConnectorObject(vFigure));

        // add entity
        if Entity <> nil then
          ToBlock.Add(Entity)
        else
        if EntityList <> nil then
        begin
          for j := 0 to EntityList.Count - 1 do
          begin
            Entity := DXF_Entity(EntityList[j]);
            ToBlock.Add(Entity);
          end;
        end;
        if OutEntity <> nil then
          OutBlock.Add(OutEntity)
        else
        if OutEntityList <> nil then
        begin
          for j := 0 to OutEntityList.Count - 1 do
          begin
            Entity := DXF_Entity(OutEntityList[j]);
            OutBlock.Add(Entity);
          end;
        end;
      end;
      // Tolik -- 08/02/2017 --
      if EntityList <> nil then
        FreeAndNil(EntityList);
      if OutEntityList <> nil then
        FreeAndNil(OutEntityList);
      //
    end;

    // создать блок и перебросить в него обьекты
    if (ToBlock.Count > 0) or (OutBlock.Count > 0) then
    begin
    // p1 := aPoint3D(p1.x - 0.5, p1.y - 0.5, p1.z);
      p1 := ModificatePoint(p1);


      str_name := AutoCorrectBlockName(aObject.Name, aObject.ID);
      str_name := CheckBlockNameExist(str_name{aObject.Name});
      BlkEntity := Block_.create(str_name{aObject.Name}, p1);

      FBlocksNames.Add(aObject.Name);

      for i := 0 to ToBlock.Count - 1 do
      begin
        Entity := DXF_Entity(ToBlock[i]);
        BLOCK_(BlkEntity).entities.Add(Entity);
      end;
      Result.add(BlkEntity);

      //
      for i := 0 to OutBlock.Count - 1 do
      begin
        Entity := DXF_Entity(OutBlock[i]);
        Result.Add(Entity);
      end;
    end;
    // Tolik -- 08/2/2017 --
    FreeAndNil(ToBlock);
    FreeAndNil(OutBlock);
    //
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TBlock', E.Message);
  end;
  // Tolik -- 08/02/2017 --   на всякий (если вдруг вылетит на ошибку)
  if EntityList <> nil then
    FreeAndNil(EntityList);
  if EntityList <> nil then
    FreeAndNil(OutEntityList);
  if ToBlock <> nil then
    ToBlock.Free;
  if OutBlock <> nil then
    OutBlock.Free;
  //
end;

function Write_TCabinet(aObject: TCabinet): TList;
var
  i: integer;
  Entity: DXF_Entity;
  EntityList: TList;
begin
  // Tolik 08/02/2017 --
  EntityList := nil;
  //
  try
    Result := nil;
    if aObject.FType = ct_Virtual then
      exit;
    if (aObject.Visible) or (aObject.FNumberObject.Visible) then
    begin
      Result := TList.create;
      if aObject.Visible then
      begin
        Entity := Write_TRectangle(TRectangle(aObject));
        Result.Add(Entity);
      end;
      if aObject.FNumberObject.Visible then
      begin
        EntityList := Write_TBlock(TFigureGrp(aObject.FNumberObject));
        for i := 0 to EntityList.Count - 1 do
        begin
          Entity := DXF_Entity(EntityList[i]);
          Result.Add(Entity);
        end;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TCabinet', E.Message);
  end;
  // Tolik 08/02/2017 --
  if EntityList <> nil then
  FreeAndNil(EntityList);
  //
end;

function Write_TCabinetExt(aObject: TCabinetExt): TList;
var
  i: integer;
  Entity: DXF_Entity;
  EntityList: TList;
begin
  // Tolik -- 08/02/2017 --
  EntityList := nil;
  //
  try
    Result := nil;
    if aObject.FType = ct_Virtual then
      exit;
    if (aObject.Visible) or (aObject.FNumberObject.Visible) then
    begin
      Result := TList.create;
      if aObject.Visible then
      begin
        Entity := Write_TPolyline(TPolyline(aObject));
        Result.Add(Entity);
      end;
      if aObject.FNumberObject.Visible then
      begin
        EntityList := Write_TBlock(TFigureGrp(aObject.FNumberObject));
        for i := 0 to EntityList.Count - 1 do
        begin
          Entity := DXF_Entity(EntityList[i]);
          Result.Add(Entity);
        end;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TCabinetExt', E.Message);
  end;
  // Tolik 08/02/2017 --
  if EntityList <> nil then
  FreeAndNil(EntityList);
  //
end;

function Write_TOrthoLine(aObject: TOrthoLine): TList;
var
  i, j, k: Integer;
  p1, p2: point3D;
  Entity: DXF_Entity;
  EntityList: TList;
  Caption: TRichTextMod;
  Rows: TFigureGrpNotMod;
  Note: TRichTextMod;
  SingleBlock: TFigureGrpMod;
  BasisConn: TConnectorObject;

  CrossPoint1, CrossPoint2: TDoublePoint;
  BasisPoints: TDoublePoint;
  Points: array [0..3] of Point3D;
  OCS_Z: Point3D;
  In_Figures: TList;

  RaiseConn: TConnectorObject;
  RowColor: Integer;
  style: string;
  GetConn: TConnectorObject;
  isUp, isDown: boolean;
  NeedExportRaise: boolean;
  // Tolik 25/09/2017 --
  reg: Hrgn;
  FirstLinePoint, LastLinePoint: TDoublePoint;
  LinePoint, LastPoint, p3, p4: TDoublePoint;
  PointInfo: POrthoLineCrossInfo;
  OCSAxis: point3D;
  DownLineDirection: Boolean;
  arcpoints: array[0..37] of Point3D;
  RotPoint: TDoublePoint;
  AngleDelta: Double;
  dist1, dist2: Double;
  // Tolik 09/11/2017
  AlternateRed: TColor;
  DrawCritCrossPoints: Boolean;
  //

  function CheckHasNocrosses(aLine: TOrthoLine): boolean;
  var i: Integer;
  begin
    Result := True;
    if aLine.CrossList.Count = 0 then
      exit;
    for i := 0 to aLine.CrossList.count - 1 do
    begin
      if POrthoLineCrossInfo(aLine.CrossList[i]).isDrawPoint then
      begin
        Result := False;
        exit;
      end;
    end;
  end;
  //
begin
  // Tolik -- 08/01/2017 --
  In_Figures := nil;
  EntityList := nil;
  OCSAxis.x := 0;
  OCSAxis.y := 0;
  OCSAxis.z := 1;
  AngleDelta := PI/36;
  //
  AlternateRed := 0;
  DrawCritCrossPoints := False;

  //if aObject.FDrawColor = clRed then

    if aObject.Owner <> nil then
      if TPowerCad(aObject.Owner).Owner <> nil then
        if (TF_Cad(TPowerCad(aObject.Owner).Owner).FListSettings.ShowTracesCrossPoints = 2) then
          //if aObject.FTraceColor = clRed then
          begin
            //AlternateRed := clFuchsia;//aObject.getclred; -- не хавает цветопередачу, делает серым или белым :(
            //AlternateRed := $FFC0CB;
          //  AlternateRed := RGB($FF, $AA, $AA);
            //DrawCritCrossPoints := (TF_Cad(TPowerCad(aObject.Owner).Owner).FListSettings.ShowTracesCrossPoints = 2);
            DrawCritCrossPoints := True;
          end;

  {if aObject.Owner <> nil then
    if TPowerCad(aObject.Owner).Owner <> nil then
       DrawCritCrossPoints := (TF_Cad(TPowerCad(aObject.Owner).Owner).FListSettings.ShowTracesCrossPoints = 2);
   }
  try
    isUp := False;
    isDown := False;
    Result := TList.Create;
    // трасса
    // ****** обычная *******************
    if (not aObject.FIsRaiseUpDown) then
    begin
      // Tolik 215/09/2017 -- простая трасса (без пересечений)
      if CheckHasNocrosses(aObject) then
      begin
        p1 := aPoint3D(aObject.actualPoints[1].x, aObject.actualPoints[1].y, aObject.ActualZOrder[1] * FKoefZ);
        p2 := aPoint3D(aObject.actualPoints[2].x, aObject.actualPoints[2].y, aObject.ActualZOrder[2] * FKoefZ);
        p1 := ModificatePoint(p1);
        p2 := ModificatePoint(p2);
        style := LineStyleToDxfLineStyle(aObject.FDrawStyle);
        if (style <> '') and (style <> 'CLEAR') then
        begin
         // if AlternateRed = 0 then
            Entity := Line_.create(p1, p2, aObject.FDrawColor);
         { else
            Entity := Line_.create(p1, p2, AlternateRed);}
          Line_(Entity).fLineStyle := style;
          // Tolik 10/07/2019 --  в данном блоке выставляется значение для адекватного отображения линии в Автокаде
          // иначе будет отображаться как сплошная ... 
          if Assigned(GCadForm) then
          begin
            Line_(Entity).LineTypeScale := FLineTypeScale; // по умолчанию -- 400, но вынесено в настройки программы (для пользователя)
            {if GCadForm.PCad.WorkHeight > GCadForm.PCad.WorkWidth then
              Line_(Entity).LineTypeScale := GCadForm.PCad.WorkHeight * 2
            else
              Line_(Entity).LineTypeScale := GCadForm.PCad.WorkWidth * 2;}
          end;
          //Line_(Entity).LineTypeScale := 1111;
          //
          Result.Add(Entity);
        end;
      end
      else
      begin
        FirstLinePoint := aObject.AP1;
        FirstLinePoint.z := aObject.ActualZOrder[1];
        LastLinePoint := aObject.AP2;
        LastLinePoint.z := aObject.ActualZOrder[2];

        if CompareValue(sqrt(sqr(aObject.AP1.x) + sqr(aObject.AP1.y)), sqrt(sqr(aObject.AP2.x) + sqr(aObject.AP2.y))) = 1 then
        begin
          FirstLinePoint := aObject.AP2;
          FirstLinePoint.z := aObject.ActualZOrder[2];
          LastLinePoint := aObject.AP1;
          LastLinePoint.z := aObject.ActualZOrder[1];
        end;
        DownLineDirection := True;
        if CompareValue(FirstLinePoint.y, LastLinePoint.y) >= 0 then
          DownLineDirection := False;

        PointInfo := POrthoLineCrossInfo(aObject.CrossList[0]);
        if PointInfo.isDrawPoint then // если это - точка отрисовки пересечения
        begin
          LinePoint.y := PointInfo.StartPoint.y - sin(aObject.FDrawFigureAngle);
          LinePoint.x := PointInfo.StartPoint.x - cos(aObject.FDrawFigureAngle);
          LinePoint.z := PointInfo.StartPoint.z;
          {
          if DownLineDirection then // в зависимости от направления отрисовки линии по оси У (вверх/вниз)
          begin
            LinePoint.y := PointInfo.StartPoint.y - sin(aObject.FDrawFigureAngle);
            LinePoint.x := PointInfo.StartPoint.x - cos(aObject.FDrawFigureAngle);
          end
          else
          begin
            LinePoint.y := PointInfo.StartPoint.y - sin(aObject.FDrawFigureAngle);
            LinePoint.x := PointInfo.StartPoint.x - cos(aObject.FDrawFigureAngle);
          end;
          }
          //arcpoints[0] := aPoint3D(LinePoint.x, LinePoint.y, 0);
          arcpoints[0] := aPoint3D(LinePoint.x, LinePoint.y, LinePoint.z * FKoefZ);
          arcpoints[0] := ModificatePoint(arcpoints[0]); // первая точка -- средина двери
          for i := 1 to 36 do
          begin
            RotPoint := RotatePoint(PointInfo.StartPoint, LinePoint, I*AngleDelta);
            if i = 36 then
            begin
              p3.x := RotPoint.x;
              p3.y := RotPoint.y;
              p3.z := RotPoint.z;
            end;
            //arcpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
            arcpoints[i] := aPoint3D(RotPoint.x, RotPoint.y, RotPoint.z  * FKoefZ);
            arcpoints[i] := ModificatePoint(arcpoints[i]);
          end;
          // Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], PointInfo.DrawColor, False);
          if ((PointInfo.isCritical = 1) and DrawCritCrossPoints) then
            Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], clRed, False)
          else
          begin
           // if AlternateRed = 0 then
              Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], aObject.FDrawColor, False);
            {else
              Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], AlternateRed, False);}
          end;

          Result.Add(Entity);
          LastPoint.x := p3.x;
          LastPoint.y := p3.y;
          LastPoint.z := p3.z;

          dist1 := Sqrt(sqr(LinePoint.x - FirstLinePoint.x) + sqr(LinePoint.y - FirstLinePoint.y));
          dist2 := Sqrt(sqr(LastPoint.x - FirstLinePoint.x) + sqr(LastPoint.y - FirstLinePoint.y));

          if CompareValue (dist1, dist2) = 1 then
          begin
            LastPoint.x := LinePoint.x;
            LastPoint.y := LinePoint.y;
            LastPoint.z := LinePoint.z;

            LinePoint.x := p3.x;
            LinePoint.y := p3.y;
            LinePoint.z := p3.z;

          end;

          //p1 := aPoint3D(FirstLinePoint.x, FirstLinePoint.y, 0);
          p1 := aPoint3D(FirstLinePoint.x, FirstLinePoint.y, FirstLinePoint.z  * FKoefZ);

          p2 := aPoint3D(LinePoint.x, LinePoint.y, LinePoint.z   * FKoefZ);

          p1 := ModificatePoint(p1);
          p2 := ModificatePoint(p2);
          style := LineStyleToDxfLineStyle(aObject.FDrawStyle);
          if (style <> '') and (style <> 'CLEAR') then
          begin
            Entity := Line_.create(p1, p2, aObject.FDrawColor);
           { if AlternateRed = 0 then
              Entity := Line_.create(p1, p2, aObject.FDrawColor)
            else
              Entity := Line_.create(p1, p2, AlternateRed);
            }
            Line_(Entity).fLineStyle := style;
            Line_(Entity).LineTypeScale := FLineTypeScale;//Tolik 15/07/2019 --
            Result.Add(Entity);
          end;

        end
        else  // если пересечение не рисуем
        begin
          //p1 := aPoint3D(FirstLinePoint.x, FirstLinePoint.y, 0);
          p1 := aPoint3D(FirstLinePoint.x, FirstLinePoint.y, FirstLinePoint.z * FKoefZ);
          //p2 := aPoint3D(PointInfo.StartPoint.x, PointInfo.StartPoint.y, 0);
          p2 := aPoint3D(PointInfo.StartPoint.x, PointInfo.StartPoint.y, PointInfo.StartPoint.z * FKoefZ);

          p1 := ModificatePoint(p1);
          p2 := ModificatePoint(p2);
          style := LineStyleToDxfLineStyle(aObject.FDrawStyle);
          if (style <> '') and (style <> 'CLEAR') then
          begin
            Entity := Line_.create(p1, p2, aObject.FDrawColor);
            {if AlternateRed = 0 then
              Entity := Line_.create(p1, p2, aObject.FDrawColor)
            else
              Entity := Line_.create(p1, p2, AlternateRed);
             }
            Line_(Entity).fLineStyle := style;
            Line_(Entity).LineTypeScale := FLineTypeScale;//Tolik 15/07/2019 --
            Result.Add(Entity);
          end;
          LastPoint.x := Pointinfo.StartPoint.x;
          LastPoint.y := PointInfo.StartPoint.y;
          LastPoint.z := PointInfo.StartPoint.z;
        end;

        if aObject.CrossList.Count > 1 then
        begin

          for i := 1 to aObject.CrossList.Count - 1 do
          begin
            PointInfo := POrthoLineCrossInfo(aObject.CrossList[i]);
            if PointInfo.isDrawPoint then
            begin
              LinePoint.y := PointInfo.StartPoint.y - sin(aObject.FDrawFigureAngle);
              LinePoint.x := PointInfo.StartPoint.x - cos(aObject.FDrawFigureAngle);
              LinePoint.z := PointInfo.StartPoint.z;
              {
              if DownLineDirection then // в зависимости от направления отрисовки линии по оси У (вверх/вниз)
              begin
                LinePoint.y := PointInfo.StartPoint.y - sin(aObject.FDrawFigureAngle);
                LinePoint.x := PointInfo.StartPoint.x - cos(aObject.FDrawFigureAngle);
              end
              else
              begin
                LinePoint.y := PointInfo.StartPoint.y - sin(aObject.FDrawFigureAngle);
                LinePoint.x := PointInfo.StartPoint.x - cos(aObject.FDrawFigureAngle);
              end;
              }


              //arcpoints[0] := aPoint3D(LinePoint.x, LinePoint.y, 0);
              arcpoints[0] := aPoint3D(LinePoint.x, LinePoint.y, LinePoint.z * FKoefZ);
              arcpoints[0] := ModificatePoint(arcpoints[0]);
              for j := 1 to 36 do
              begin
                RotPoint := RotatePoint(PointInfo.StartPoint, LinePoint, J*AngleDelta);
                if j = 36 then
                begin
                  p3.x := RotPoint.x;
                  p3.y := RotPoint.y;
                  p3.z := RotPoint.z;
                end;
                //arcpoints[j] := aPoint3D(RotPoint.x, RotPoint.y,0);
                arcpoints[j] := aPoint3D(RotPoint.x, RotPoint.y, RotPoint.z * FKoefZ);
                arcpoints[j] := ModificatePoint(arcpoints[j]);
              end;

              //Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], PointInfo.DrawColor, False);
              if ((PointInfo.isCritical = 1) and DrawCritCrossPoints) then
                Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], clRed, False)
              else
              begin
               // if AlternateRed = 0 then
                  Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], aObject.FDrawColor, False);
               { else
                  Entity := Polyline_.create(OCSAxis, 37, @arcpoints[0], AlternateRed, False);}
              end;

              Result.Add(Entity);

              {LastPoint.x := p3.x;
              LastPoint.y := p3.y;}

              dist1 := Sqrt(sqr(LinePoint.x - FirstLinePoint.x) + sqr(LinePoint.y - FirstLinePoint.y));
              dist2 := Sqrt(sqr(p3.x - FirstLinePoint.x) + sqr(p3.y - FirstLinePoint.y));

              if CompareValue (dist1, dist2) = 1 then
              begin
                //p2 := aPoint3D(p3.x, p3.y, 0);
                p2 := aPoint3D(p3.x, p3.y, p3.z * FKoefZ);
              end
              else
                //p2 := aPoint3D(LinePoint.x, LinePoint.y, 0);
                p2 := aPoint3D(LinePoint.x, LinePoint.y, LinePoint.z * FKoefZ);

              //p1 := aPoint3D(LastPoint.x, LastPoint.y, 0);
              p1 := aPoint3D(LastPoint.x, LastPoint.y, LastPoint.z * FKoefZ);
              p1 := ModificatePoint(p1);
              p2 := ModificatePoint(p2);
              style := LineStyleToDxfLineStyle(aObject.FDrawStyle);
              if (style <> '') and (style <> 'CLEAR') then
              begin
                Entity := Line_.create(p1, p2, aObject.FDrawColor);
               { if AlternateRed = 0 then
                  Entity := Line_.create(p1, p2, aObject.FDrawColor)
                else
                  Entity := Line_.create(p1, p2, AlternateRed);
                }
                Line_(Entity).fLineStyle := style;
                Line_(Entity).LineTypeScale := FLineTypeScale;//Tolik 15/07/2019 --
                Result.Add(Entity);
              end;

              if CompareValue (dist1, dist2) = 1 then
              begin
                LastPoint := LinePoint
              end
              else
                LastPoint := p3;
            end
            else
            begin
              //p1 := aPoint3D(LastPoint.x, LastPoint.y, 0);
              p1 := aPoint3D(LastPoint.x, LastPoint.y, LastPoint.z * FKoefZ);
              //p2 := aPoint3D(PointInfo.StartPoint.x, PointInfo.StartPoint.y, 0);
              p2 := aPoint3D(PointInfo.StartPoint.x, PointInfo.StartPoint.y, PointInfo.StartPoint.z * FKoefZ);
              p1 := ModificatePoint(p1);
              p2 := ModificatePoint(p2);
              style := LineStyleToDxfLineStyle(aObject.FDrawStyle);
              if (style <> '') and (style <> 'CLEAR') then
              begin
                Entity := Line_.create(p1, p2, aObject.FDrawColor);
                {if AlternateRed = 0 then
                  Entity := Line_.create(p1, p2, aObject.FDrawColor)
                else
                  Entity := Line_.create(p1, p2, AlternateRed);}

                Line_(Entity).fLineStyle := style;
                Line_(Entity).LineTypeScale := FLineTypeScale;//Tolik 15/07/2019 --
                Result.Add(Entity);
              end;

              LastPoint.x := Pointinfo.StartPoint.x;
              LastPoint.y := PointInfo.StartPoint.y;
              LastPoint.z := PointInfo.StartPoint.z;
            end;
          end;

        end;
        //p1 := aPoint3D(LastPoint.x, LastPoint.y, 0);
        p1 := aPoint3D(LastPoint.x, LastPoint.y, LastPoint.z * FKoefZ);
        //p2 := aPoint3D(LastLinePoint.x, LastLinePoint.y, 0);
        p2 := aPoint3D(LastLinePoint.x, LastLinePoint.y, LastLinePoint.z * FKoefZ);
        p1 := ModificatePoint(p1);
        p2 := ModificatePoint(p2);
        style := LineStyleToDxfLineStyle(aObject.FDrawStyle);
        if (style <> '') and (style <> 'CLEAR') then
        begin
          Entity := Line_.create(p1, p2, aObject.FDrawColor);
          {if AlternateRed = 0 then
            Entity := Line_.create(p1, p2, aObject.FDrawColor)
          else
            Entity := Line_.create(p1, p2, AlternateRed);}

          Line_(Entity).fLineStyle := style;
          Line_(Entity).LineTypeScale := FLineTypeScale;//Tolik 15/07/2019 --
          Result.Add(Entity);
        end;
        //DEngine.DrawLine(LastPoint, LastLinePoint, LineColor, LineWidth, ord(LinePenstyle),0);
      end;
    end
    else
    // ******** спуск-подъем *************
    begin
      BasisConn := aObject.FObjectFromRaisedLine;
      NeedExportRaise := Not FExportZ;
      if (BasisConn <> nil) then
      begin
        RaiseConn := GetRaiseByRaiseLine(aObject);
        if (RaiseConn = nil) then
          RowColor := clBlack
        else
        if (RaiseConn.FConnRaiseType = crt_OnFloor) then
          RowColor := clBlack
        else
        if (RaiseConn.FConnRaiseType = crt_BetweenFloorUp) or (RaiseConn.FConnRaiseType = crt_BetweenFloorDown) then
        begin
          NeedExportRaise := True;
          RowColor := clBlue;
          if RaiseConn.FConnRaiseType = crt_BetweenFloorUp then
            isUp := True;
          if RaiseConn.FConnRaiseType = crt_BetweenFloorDown then
            isDown := True;
        end
        else
        if (RaiseConn.FConnRaiseType = crt_TrunkUp) or (RaiseConn.FConnRaiseType = crt_TrunkDown) then
        begin
          RowColor := clGreen;
          NeedExportRaise := True;
        end;
        if NeedExportRaise then
        begin
          // создать линию
          if BasisConn.DrawFigure = nil then
          begin
            BasisPoints.x := BasisConn.ActualPoints[1].x + BasisConn.GrpSizeX / 2;
            BasisPoints.y := BasisConn.ActualPoints[1].y - BasisConn.GrpSizeY / 2;
          end
          else
          begin
            if BasisConn.DrawFigure.InFigures.Count = 0 then
            begin
              BasisPoints.x := BasisConn.ActualPoints[1].x + BasisConn.GrpSizeX / 2;
              BasisPoints.y := BasisConn.ActualPoints[1].y - BasisConn.GrpSizeY / 2;
            end
            else
            begin
              BasisPoints.x := BasisConn.DrawFigure.CenterPoint.x + BasisConn.GrpSizeX / 2;
              BasisPoints.y := BasisConn.DrawFigure.CenterPoint.y - BasisConn.GrpSizeY / 2;
            end;
          end;
          p1 := aPoint3D(BasisPoints.x, BasisPoints.y, BasisConn.ActualZOrder[1] * FKoefZ);
          p2 := aPoint3D(BasisPoints.x + 4, BasisPoints.y - 4, BasisConn.ActualZOrder[1] * FKoefZ);
          p1 := ModificatePoint(p1);
          p2 := ModificatePoint(p2);
          Entity := Line_.create(p1, p2, RowColor);
          Result.Add(Entity);

          OCS_Z := aPoint3D(0, 0, 1);
          // наконечник
          if aObject.FLineRaiseType = lrt_Up then
          begin
            if Not isDown then
            begin
              Points[0] := aPoint3D(BasisPoints.x + 2, BasisPoints.y - 3, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[1] := aPoint3D(BasisPoints.x + 4, BasisPoints.y - 4, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[2] := aPoint3D(BasisPoints.x + 3, BasisPoints.y - 2, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[3] := aPoint3D(BasisPoints.x + 2, BasisPoints.y - 3, BasisConn.ActualZOrder[1] * FKoefZ);
            end
            else
            begin
              Points[0] := aPoint3D(BasisPoints.x + 1, BasisPoints.y - 2, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[1] := aPoint3D(BasisPoints.x, BasisPoints.y, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[2] := aPoint3D(BasisPoints.x + 2, BasisPoints.y - 1, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[3] := aPoint3D(BasisPoints.x + 1, BasisPoints.y - 2, BasisConn.ActualZOrder[1] * FKoefZ);
            end;
          end;
          if aObject.FLineRaiseType = lrt_Down then
          begin
            if Not isUp then
            begin
              Points[0] := aPoint3D(BasisPoints.x + 1, BasisPoints.y - 2, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[1] := aPoint3D(BasisPoints.x, BasisPoints.y, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[2] := aPoint3D(BasisPoints.x + 2, BasisPoints.y - 1, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[3] := aPoint3D(BasisPoints.x + 1, BasisPoints.y - 2, BasisConn.ActualZOrder[1] * FKoefZ);
            end
            else
            begin
              Points[0] := aPoint3D(BasisPoints.x + 2, BasisPoints.y - 3, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[1] := aPoint3D(BasisPoints.x + 4, BasisPoints.y - 4, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[2] := aPoint3D(BasisPoints.x + 3, BasisPoints.y - 2, BasisConn.ActualZOrder[1] * FKoefZ);
              Points[3] := aPoint3D(BasisPoints.x + 2, BasisPoints.y - 3, BasisConn.ActualZOrder[1] * FKoefZ);
            end;
          end;
          points[0] := ModificatePoint(points[0]);
          points[1] := ModificatePoint(points[1]);
          points[2] := ModificatePoint(points[2]);
          points[3] := ModificatePoint(points[3]);
          Entity := Polyline_.create(OCS_Z, 4, @points[0], RowColor, true);
          Result.Add(Entity);
        end;
      end;
      // сама линия, вертикальная
      p1 := aPoint3D(aObject.actualPoints[1].x, aObject.actualPoints[1].y, aObject.ActualZOrder[1] * FKoefZ);
      p2 := aPoint3D(aObject.actualPoints[2].x, aObject.actualPoints[2].y, aObject.ActualZOrder[2] * FKoefZ);
      // IGOR add 2013-10-01
      // D0000006059
      // переназначить первую сторону
      if aObject.JoinConnector1 <> nil then
      begin
        if TConnectorObject(aObject.JoinConnector1).JoinedConnectorsList.Count = 0 then
          GetConn := TConnectorObject(aObject.JoinConnector1)
        else
          GetConn := TConnectorObject(TConnectorObject(aObject.JoinConnector1).JoinedConnectorsList[0]);
        if GetConn <> nil then
        begin
          p1.x := GetConn.ActualPoints[1].x;
          p1.y := GetConn.ActualPoints[1].y;
        end;
      end;
      // переназначить вторую сторону
      if aObject.JoinConnector2 <> nil then
      begin
        if TConnectorObject(aObject.JoinConnector2).JoinedConnectorsList.Count = 0 then
          GetConn := TConnectorObject(aObject.JoinConnector2)
        else
          GetConn := TConnectorObject(TConnectorObject(aObject.JoinConnector2).JoinedConnectorsList[0]);
        if GetConn <> nil then
        begin
          p2.x := GetConn.ActualPoints[1].x;
          p2.y := GetConn.ActualPoints[1].y;
        end;
      end;
      // IGOR add 2013-10-01 END

      p1 := ModificatePoint(p1);
      p2 := ModificatePoint(p2);
      Entity := Line_.create(p1, p2, aObject.FDrawColor);
      Result.Add(Entity);
      //
    end;
    // подпись
    if (GCadForm.FShowLinesCaptions) and (aObject.ShowCaptions) and (aObject.CaptionsGroup <> nil) then
    begin
      Caption := TRichTextMod(aObject.CaptionsGroup.InFigures[1]);
      Entity := Write_TRichText(Caption, aObject.ActualZOrder[1] * FKoefZ);
      Entity.SCS_Layer_Handle := integer(TLayer(GaPCad.Layers[3]));
      Result.Add(Entity);
    end;
    // выноска
    if (GCadForm.FShowLinesNotes) and (aObject.ShowNotes) and (aObject.NotesGroup <> nil) then
    begin
      Rows := TFigureGrpNotMod(aObject.NotesGroup.InFigures[0]);
      Note := TRichTextMod(aObject.NotesGroup.InFigures[1]);
      EntityList := Write_TBlock(Rows, aObject.ActualZOrder[1] * FKoefZ);
      for i := 0 to EntityList.Count - 1 do
      begin
        Entity := DXF_Entity(EntityList[i]);
        Entity.SCS_Layer_Handle := integer(TLayer(GaPCad.Layers[5]));
        Result.Add(Entity);
      end;
      // Tolik -- 08/02/2017 --
      if EntityList <> nil then
        FreeAndNil(EntityList);
      //
      Entity := Write_TRichText(Note, aObject.ActualZOrder[1] * FKoefZ);
      Entity.SCS_Layer_Handle := integer(TLayer(GaPCad.Layers[5]));
      Result.Add(Entity);
    end;
    // УГО
    if (not aObject.FIsRaiseUpDown) and (aObject.DrawFigure <> nil) then
    begin
      In_Figures := aObject.DrawFigure.InFigures;//GetDrawFigureWithoutDuplicates(aObject.DrawFigure.InFigures);
      for i := 0 to In_Figures.Count - 1 do
      begin
        SingleBlock := TFigureGrpMod(In_Figures[i]);
        // Tolik -- 26/09/2017 --
        if SingleBlock.Visible then
        begin
          EntityList := Write_TBlock(SingleBlock, aObject.ActualZOrder[1] * FKoefZ);
          for j := 0 to EntityList.Count - 1 do
          begin
            Entity := DXF_Entity(EntityList[j]);
            Result.Add(Entity);
          end;
        end;
        // Tolik -- 08/02/2017 --
        if EntityList <> nil then
          FreeAndNil(EntityList);
        //
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TOrthoLine', E.Message);
  end;
end;

function Write_TConnectorObject(aObject: TConnectorObject): TList;
var
  i, j: Integer;
  p1: point3D;
  OCS_Z: point3D;
  Entity: DXF_Entity;
  EntityList: TList;
  Caption: TRichTextMod;
  Rows: TFigureGrpNotMod;
  Note: TRichTextMod;
  SingleBlock, InSingleBlock: TFigureGrpMod;
begin
  // Tolik -- 08/02/2017 --
  EntityList := nil;
  //
  try
    Result := TList.Create;
    // коннектор
    OCS_Z := aPoint3D(0, 0, 1);
    p1 := aPoint3D(aObject.ActualPoints[1].x, aObject.ActualPoints[1].y, aObject.ActualZOrder[1] * FKoefZ);
    p1 := ModificatePoint(p1);
    Entity := Point_.create(OCS_Z, p1, aObject.color);
    Result.Add(Entity);
    // подпись
    if (GCadForm.FShowConnectorsCaptions) and (aObject.ShowCaptions) and (aObject.CaptionsGroup <> nil) then
    begin
      Caption := aObject.CaptionsGroup;
      Entity := Write_TRichText(Caption, aObject.ActualZOrder[1] * FKoefZ);
      Entity.SCS_Layer_Handle := integer(TLayer(GaPCad.Layers[4]));
      Result.Add(Entity);
    end;
    // выноска
    if (GCadForm.FShowConnectorsNotes) and (aObject.ShowNotes) and (aObject.NotesGroup <> nil) then
    begin
      Rows := TFigureGrpNotMod(aObject.NotesGroup.InFigures[0]);
      Note := TRichTextMod(aObject.NotesGroup.InFigures[1]);
      EntityList := Write_TBlock(Rows, aObject.ActualZOrder[1] * FKoefZ);
      for i := 0 to EntityList.Count - 1 do
      begin
        Entity := DXF_Entity(EntityList[i]);
        Entity.SCS_Layer_Handle := integer(TLayer(GaPCad.Layers[6]));
        Result.Add(Entity);
      end;
      // Tolik -- 08/02/2017 --
      if EntityList <> nil then
        FreeAndNil(EntityList);
      //
      Entity := Write_TRichText(Note, aObject.ActualZOrder[1] * FKoefZ);
      Entity.SCS_Layer_Handle := integer(TLayer(GaPCad.Layers[6]));
      Result.Add(Entity);
    end;
    // УГО
    if (aObject.ConnectorType <> ct_Clear) and (aObject.DrawFigure <> nil) then
    begin
      EntityList := Write_TBlock(aObject.DrawFigure, aObject.ActualZOrder[1] * FKoefZ);
      for i := 0 to EntityList.Count - 1 do
      begin
        Entity := DXF_Entity(EntityList[i]);
        Result.Add(Entity);
      end;
      // Tolik -- 08/02/2017 --
      if EntityList <> nil then
        FreeAndNil(EntityList);
      //
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TConnectorObject', E.Message);
  end;
end;

function Write_TSCSFigureGrp(aObject: TSCSFigureGrp): TList;
var
  i, j: integer;
  InFigure: TFigure;
  Entity: DXF_Entity;
  EntityList: TList;
begin
  // Tolik 08/02/2017 --
  EntityList := Nil;
  //
  try
    Result := TList.Create;
    for i := 0 to aObject.InFigures.Count - 1 do
    begin
      InFigure := TFigure(aObject.InFigures[i]);
      if (InFigure.ClassName = 'TOrthoLine') then
        EntityList := Write_TOrthoLine(TOrthoLine(InFigure));
      if (InFigure.ClassName = 'TConnectorObject') then
        EntityList := Write_TConnectorObject(TConnectorObject(InFigure));
      // Tolik 08/02/2017 --
      if EntityList <> nil then
      begin
      //
        for j := 0 to EntityList.Count - 1 do
        begin
          Entity := DXF_Entity(EntityList[j]);
          Result.Add(Entity);
        end;
        // Tolik 08/02/2017 --
        FreeAndNil(EntityList);
        //
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TSCSFigureGrp', E.Message);
  end;
end;

function Write_TNet(aObject: TNet): TList;
var
  i, j, k: integer;
  Path: TNetPath;
  Door: TNetDoor;
  Window: TNetDoor;
  Column: TNetCol;
  Entity: DXF_Entity;
  EntityList: TList;
begin
  // Tolik -- 08/02/2017 --
  EntityList := nil;
  //
  try
    Result := TList.Create;
    // Сегменты
    for i := 0 to aObject.Paths.Count - 1 do
    begin
      Path := TNetPath(aObject.Paths[i]);
      EntityList := Write_TNetPath(Path);
      // Tolik -- 08/02/2017 --
      if EntityList <> nil then
      begin
      //
        for j := 0 to EntityList.Count - 1 do
        begin
          Entity := DXF_Entity(EntityList[j]);
          Result.Add(Entity);
        end;
        FreeAndNil(EntityList);
      end;
    end;
    // Окна и Двери
    for i := 0 to aObject.Paths.Count - 1 do
    begin
      Path := TNetPath(aObject.Paths[i]);
      for j := 0 to Path.Doors.Count - 1 do
      begin
        Door := TNetDoor(Path.Doors[j]);
        EntityList := Write_TNetDoor(Door);
        // Tolik 08/02/2017 --
        if EntityList <> nil then
        begin
        //
          for k := 0 to EntityList.Count - 1 do
          begin
            Entity := DXF_Entity(EntityList[k]);
            Result.Add(Entity);
          end;
          FreeAndNil(EntityList);
        end;
      end;
    end;
    // Колонны
    for i := 0 to aObject.Structs.Count - 1 do
    begin
      Column := TNetCol(aObject.Structs[i]);
      Entity := Write_TNetCol(Column);
      if Entity <> nil then
        Result.Add(Entity);
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TNet', E.Message);
  end;
end;

function Write_TNetPath(aObject: TNetPath): TList;
var
  i: integer;
  door: TnetDoor;
  p1, p2: point3D;
  xL1, xR1, da1, da2, db1, db2: TDoublePoint;
  Entity: DXF_Entity;
  style: string;
begin
  try
    Result := TList.Create;
    style := LineStyleToDxfLineStyle(ord(aObject.FPathStyle));
    if (style <> '') and (style <> 'CLEAR') then
    begin
      if aObject.Doors.Count > 0 then
      begin
        xL1 := aObject.l1;
        xR1 := aObject.r1;
        for i := 0 to aObject.Doors.Count - 1 do
        begin
          Door := TnetDoor(aObject.Doors[i]);
          da1 := Door.a1;
          da2 := Door.a2;
          db1 := Door.b1;
          db2 := Door.b2;
          p1 := aPoint3D(xl1.x, xl1.y, xl1.z);
          p2 := aPoint3D(da1.x, da1.y, da1.z);
          p1 := ModificatePoint(p1);
          p2 := ModificatePoint(p2);
          Entity := Line_.create(p1, p2, 0);
          Line_(Entity).fLineStyle := style;
          Result.Add(Entity);
          p1 := aPoint3D(xr1.x, xr1.y, xr1.z);
          p2 := aPoint3D(db1.x, db1.y, db1.z);
          p1 := ModificatePoint(p1);
          p2 := ModificatePoint(p2);
          Entity := Line_.create(p1, p2, 0);
          Line_(Entity).fLineStyle := style;
          Result.Add(Entity);
          p1 := aPoint3D(da1.x, da1.y, da1.z);
          p2 := aPoint3D(db1.x, db1.y, db1.z);
          p1 := ModificatePoint(p1);
          p2 := ModificatePoint(p2);
          Entity := Line_.create(p1, p2, 0);
          Result.Add(Entity);
          p1 := aPoint3D(da2.x, da2.y, da2.z);
          p2 := aPoint3D(db2.x, db2.y, db2.z);
          p1 := ModificatePoint(p1);
          p2 := ModificatePoint(p2);
          Entity := Line_.create(p1, p2, 0);
          Result.Add(Entity);
          xl1 := da2;
          xr1 := db2;
        end;
        p1 := aPoint3D(xl1.x, xl1.y, xl1.z);
        p2 := aPoint3D(aObject.l2.x, aObject.l2.y, aObject.l2.z);
        p1 := ModificatePoint(p1);
        p2 := ModificatePoint(p2);
        Entity := Line_.create(p1, p2, 0);
        Line_(Entity).fLineStyle := style;
        Result.Add(Entity);
        p1 := aPoint3D(xr1.x, xr1.y, xr1.z);
        p2 := aPoint3D(aObject.r2.x, aObject.r2.y, aObject.r2.z);
        p1 := ModificatePoint(p1);
        p2 := ModificatePoint(p2);
        Entity := Line_.create(p1, p2, 0);
        Line_(Entity).fLineStyle := style;
        Result.Add(Entity);
      end
      else
      begin
        p1 := aPoint3D(aObject.l1.x, aObject.l1.y, aObject.l1.z);
        p2 := aPoint3D(aObject.l2.x, aObject.l2.y, aObject.l2.z);
        p1 := ModificatePoint(p1);
        p2 := ModificatePoint(p2);
        Entity := Line_.create(p1, p2, 0);
        Line_(Entity).fLineStyle := style;
        Result.Add(Entity);
        p1 := aPoint3D(aObject.r1.x, aObject.r1.y, aObject.r1.z);
        p2 := aPoint3D(aObject.r2.x, aObject.r2.y, aObject.r2.z);
        p1 := ModificatePoint(p1);
        p2 := ModificatePoint(p2);
        Entity := Line_.create(p1, p2, 0);
        Line_(Entity).fLineStyle := style;
        Result.Add(Entity);
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TNetPath', E.Message);
  end;
end;

function Write_TNetDoor(aObject: TNetDoor): TList;
var
  i: integer;
  door: TnetDoor;
  p1, p2: point3D;
  Entity: DXF_Entity;
  // Tolik -- 22/09/2017 --
  HalfWidth, DoorAngle: Double;
  DoorMiddlePoint: TDoublePoint;
  ArcPoint: TDoublePoint;
  OCSAxis: point3D;
  RotPoint: TDoublePoint;
  RotAngle1, RotAngle2: Double;
  dp1, dp2: TDoublePoint;
  AngleDelta: Double;

  points: array[0..19] of Point3D;
  halfpoints: array[0..10] of Point3D;
  //
begin
  try
    // Tolik --25/09/2017 --
    AngleDelta := PI/36; // 5 градусов
    OCSAxis.x := 0;
    OCSAxis.y := 0;
    OCSAxis.z := 1;
    //
    Result := TList.Create;
    p1 := aPoint3D(aObject.a1.x, aObject.a1.y, 0);
    p2 := aPoint3D(aObject.b1.x, aObject.b1.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, 0);
    Result.Add(Entity);
    p1 := aPoint3D(aObject.a2.x, aObject.a2.y, 0);
    p2 := aPoint3D(aObject.b2.x, aObject.b2.y, 0);
    p1 := ModificatePoint(p1);
    p2 := ModificatePoint(p2);
    Entity := Line_.create(p1, p2, 0);
    Result.Add(Entity);
    if aObject.Window then
    begin
      p1 := aPoint3D(aObject.a1.x, aObject.a1.y, 0);
      p2 := aPoint3D(aObject.a2.x, aObject.a2.y, 0);
      p1 := ModificatePoint(p1);
      p2 := ModificatePoint(p2);
      Entity := Line_.create(p1, p2, 0);
      Result.Add(Entity);
      p1 := aPoint3D(aObject.b1.x, aObject.b1.y, 0);
      p2 := aPoint3D(aObject.b2.x, aObject.b2.y, 0);
      p1 := ModificatePoint(p1);
      p2 := ModificatePoint(p2);
      Entity := Line_.create(p1, p2, 0);
      Result.Add(Entity);
      p1 := aPoint3D(aObject.ca1.x, aObject.ca1.y, 0);
      p2 := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
      p1 := ModificatePoint(p1);
      p2 := ModificatePoint(p2);
      Entity := Line_.create(p1, p2, 0);
      Result.Add(Entity);
      p1 := aPoint3D(aObject.cb1.x, aObject.cb1.y, 0);
      p2 := aPoint3D(aObject.cb2.x, aObject.cb2.y, 0);
      p1 := ModificatePoint(p1);
      p2 := ModificatePoint(p2);
      Entity := Line_.create(p1, p2, 0);
      Result.Add(Entity);
    end
    else
    begin
      p1 := aPoint3D(aObject.ca1.x, aObject.ca1.y, 0);
      p2 := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
      p1 := ModificatePoint(p1);
      p2 := ModificatePoint(p2);
      Entity := Line_.create(p1, p2, 0);
      Result.Add(Entity);
      p1 := aPoint3D(aObject.cb1.x, aObject.cb1.y, 0);
      p2 := aPoint3D(aObject.cb2.x, aObject.cb2.y, 0);
      p1 := ModificatePoint(p1);
      p2 := ModificatePoint(p2);
      Entity := Line_.create(p1, p2, 0);
      Result.Add(Entity);
      // Tolik -- 22/09/2017 --
      if aObject.Doubled then // двойные двери
      begin
        if not aObject.Opened then  // просто двойную -- перечеркиваем
          if not aObject.HalfOpened then
          begin
            p1 := aPoint3D((aObject.a1.x + aObject.a2.x)/2, (aObject.a1.y + aObject.a2.y)/2, 0);
            p2 := aPoint3D((aObject.b1.x + aObject.b2.x)/2, (aObject.b1.y + aObject.b2.y)/2, 0);
            p1 := ModificatePoint(p1);
            p2 := ModificatePoint(p2);
            Entity := Line_.create(p1, p2, 0);
            Result.Add(Entity);
          end;

        if aObject.Mirrored then // если зеркально
        begin
          // открытая и полуоткрытая нарисуется добавлением арок и линий
          if aObject.Opened then // если рисовать как открытую дверь  (угол арки 90 градусов)
          begin
            DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2); // угол поворота двери 
            DoorMiddlePoint := DoublePoint((aObject.ca1.x + aObject.ca2.x)/2, (aObject.ca1.y + aObject.ca2.y)/2); // средина двери
            p1 := aPoint3D(aObject.ca1.x, aObject.ca1.y,0);
            p2 := aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
            p1 := ModificatePoint(p1);
            p2 := ModificatePoint(p2);

            HalfWidth := Sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y))/2;

            RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, -PI/2);
            p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p2 := ModificatePoint(p2);
            Entity := Line_.create(p1, p2, 0);
            Result.Add(Entity);

            p2 := aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
            p2 := ModificatePoint(p2);

            RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, PI/2);
            p1 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p1 := ModificatePoint(p1);
            Entity := Line_.create(p1, p2, 0);
            Result.Add(Entity);

            // арки полилиниями
            points[0] := aPoint3D(DoorMiddlePoint.x, DoorMiddlePoint.y, 0);
            points[0] := ModificatePoint(points[0]); // первая точка -- средина двери
            for i := 1 to 18 do
            begin
              RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, -I*AngleDelta);
              points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              points[i] := ModificatePoint(points[i]);
            end;

            Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
            Result.Add(Entity);
            for i := 1 to 18 do
            begin
              RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, I*AngleDelta);
              points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              points[i] := ModificatePoint(points[i]);
            end;
            Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
            Result.Add(Entity);
          end
          else
          if aObject.HalfOpened then
          begin
            DoorAngle := GetRadOfLine(aObject.cb1, aObject.cb2); // угол поворота двери
            DoorMiddlePoint := DoublePoint((aObject.cb1.x + aObject.cb2.x)/2, (aObject.cb1.y + aObject.cb2.y)/2); // средина двери

            p1 := aPoint3D(aObject.cb1.x, aObject.cb1.y,0);
            p2 := aPoint3D(aObject.cb2.x, aObject.cb2.y,0);
            p1 := ModificatePoint(p1);
            p2 := ModificatePoint(p2);

            HalfWidth := Sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y))/2;

            RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, -PI/4);
            p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p2 := ModificatePoint(p2);
            Entity := Line_.create(p1, p2, 0);
            Result.Add(Entity);

            p2 := aPoint3D(aObject.cb2.x, aObject.cb2.y,0);
            p2 := ModificatePoint(p2);

            RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, PI/4);
            p1 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p1 := ModificatePoint(p1);
            Entity := Line_.create(p1, p2, 0);
            Result.Add(Entity);

            halfpoints[0] := aPoint3D(DoorMiddlePoint.x, DoorMiddlePoint.y, 0);
            halfpoints[0] := ModificatePoint(halfpoints[0]); // первая точка -- средина двери
            for i := 1 to 9 do
            begin
              RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, -I*AngleDelta);
              halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              halfpoints[i] := ModificatePoint(halfpoints[i]);
            end;

            Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
            Result.Add(Entity);
            for i := 1 to 9 do
            begin
              RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, I*AngleDelta);
              halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              halfpoints[i] := ModificatePoint(halfpoints[i]);
            end;
            Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
            Result.Add(Entity);
          end;
        end
        else
        begin // обычное (незеркальное) отображение
          if aObject.Opened then // если рисовать как открытую дверь  (угол арки 90 градусов)
          begin
            //DoorAngle := ((GetRadOfLine(aObject.ca1, aObject.ca2))*180)/PI; // угол поворота двери
            DoorMiddlePoint := DoublePoint((aObject.ca1.x + aObject.ca2.x)/2, (aObject.ca1.y + aObject.ca2.y)/2); // средина двери
            DoorAngle := ((GetRadOfLine(aObject.ca1, DoorMiddlePoint))*180)/PI; // угол поворота двери
            p1 := aPoint3D(aObject.ca1.x, aObject.ca1.y,0);
            p2 := aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
            p1 := ModificatePoint(p1);
            p2 := ModificatePoint(p2);

            //
            RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, PI/2);
            RotAngle1 := ((GetRadOfLine(aObject.ca1, RotPoint))*180)/PI;
            p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p2 := ModificatePoint(p2);
            Entity := Line_.create(p1, p2, 0);


            //RotAngle1 := ((GetRadOfLine(dp2, dp1))*180)/PI;
            Result.Add(Entity);

            p2 := aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
            p2 := ModificatePoint(p2);

            RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, -PI/2);
            RotAngle2 := ((GetRadOfLine(aObject.ca2, RotPoint))*180)/PI;

            p1 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p1 := ModificatePoint(p1);
            Entity := Line_.create(p1, p2, 0);

            //RotAngle2 := ((GetRadOfLine(dp2, dp1))*180)/PI;
            Result.Add(Entity);

            //
            p1 := aPoint3D(aObject.ca1.x, aObject.ca1.y,0);
            p2 := aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
            p1 := ModificatePoint(p1);
            p2 := ModificatePoint(p2);

            HalfWidth := Sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y))/2;

            // арки полилиниями
            points[0] := aPoint3D(DoorMiddlePoint.x, DoorMiddlePoint.y, 0);
            points[0] := ModificatePoint(points[0]); // первая точка -- средина двери
            for i := 1 to 18 do
            begin
              RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, I*AngleDelta);
              points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              points[i] := ModificatePoint(points[i]);
            end;

            Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
            Result.Add(Entity);
            for i := 1 to 18 do
            begin
              RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, -I*AngleDelta);
              points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              points[i] := ModificatePoint(points[i]);
            end;
            Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
            Result.Add(Entity);
          end
          else
          if aObject.HalfOpened then
          begin
            DoorAngle := GetRadOfLine(aObject.cb1, aObject.cb2); // угол поворота двери
            DoorMiddlePoint := DoublePoint((aObject.cb1.x + aObject.cb2.x)/2, (aObject.cb1.y + aObject.cb2.y)/2); // средина двери

            p1 := aPoint3D(aObject.cb1.x, aObject.cb1.y,0);
            p2 := aPoint3D(aObject.cb2.x, aObject.cb2.y,0);
            p1 := ModificatePoint(p1);
            p2 := ModificatePoint(p2);

            HalfWidth := Sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y))/2;

            RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, PI/4);
            p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p2 := ModificatePoint(p2);
            Entity := Line_.create(p1, p2, 0);
            Result.Add(Entity);

            p2 := aPoint3D(aObject.cb2.x, aObject.cb2.y,0);
            p2 := ModificatePoint(p2);

            RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, -PI/4);
            p1 := aPoint3D(RotPoint.x, RotPoint.y,0);
            p1 := ModificatePoint(p1);
            Entity := Line_.create(p1, p2, 0);
            Result.Add(Entity);

            halfpoints[0] := aPoint3D(DoorMiddlePoint.x, DoorMiddlePoint.y, 0);
            halfpoints[0] := ModificatePoint(halfpoints[0]); // первая точка -- средина двери
            for i := 1 to 9 do
            begin
              RotPoint := RotatePoint(aObject.ca1, DoorMiddlePoint, I*AngleDelta);
              halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              halfpoints[i] := ModificatePoint(halfpoints[i]);
            end;

            Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
            Result.Add(Entity);
            for i := 1 to 9 do
            begin
              RotPoint := RotatePoint(aObject.ca2, DoorMiddlePoint, -I*AngleDelta);
              halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
              halfpoints[i] := ModificatePoint(halfpoints[i]);
            end;
            Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
            Result.Add(Entity);
          end;
        end;
      end
      else // простые двери
      begin
        if not aObject.Mirrored then // не зеркально
        begin
          if not aObject.LeftRight then //левосторонняя дверь
          begin
            if aObject.Opened then // если рисовать как открытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2);
              p1 :=aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
              p1 := ModificatePoint(p1);

              RotPoint := RotatePoint(aObject.ca2, aObject.ca1, -PI/2);

              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);
              // арка
              points[0] := aPoint3D(aObject.ca1.x, aObject.ca1.y, 0);
              points[0] := ModificatePoint(points[0]);
              for i := 1 to 18 do
              begin
                RotPoint := RotatePoint(aObject.ca2, aObject.ca1, -I*AngleDelta);
                points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                points[i] := ModificatePoint(points[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
              Result.Add(Entity);
            end
            else
            if aObject.HalfOpened then // если рисовать как полуоткрытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.cb1, aObject.cb2);
              p1 :=aPoint3D(aObject.cb2.x, aObject.cb2.y,0);
              p1 := ModificatePoint(p1);

              RotPoint := RotatePoint(aObject.cb2, aObject.cb1, -PI/4);

              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);

              halfpoints[0] := aPoint3D(aObject.cb1.x, aObject.cb1.y, 0);
              halfpoints[0] := ModificatePoint(halfpoints[0]);
              for i := 1 to 9 do
              begin
                RotPoint := RotatePoint(aObject.cb2, aObject.cb1, -I*AngleDelta);
                halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                halfpoints[i] := ModificatePoint(halfpoints[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
              Result.Add(Entity);
            end;
          end
          else              // правосторонняя дверь
          begin
            if aObject.Opened then // если рисовать как открытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2);

              p1 :=aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
              p1 := ModificatePoint(p1);


              RotPoint := RotatePoint(aObject.ca1, aObject.ca2, PI/2);
              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);

              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);
              // арка
              points[0] := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
              points[0] := ModificatePoint(points[0]);
              for i := 1 to 18 do
              begin
                RotPoint := RotatePoint(aObject.ca1, aObject.ca2, I*AngleDelta);
                points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                points[i] := ModificatePoint(points[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
              Result.Add(Entity);

            end
            else
            if aObject.HalfOpened then // если рисовать как полуоткрытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2);

              p1 :=aPoint3D(aObject.ca2.x, aObject.ca2.y,0);
              p1 := ModificatePoint(p1);


              RotPoint := RotatePoint(aObject.ca1, aObject.ca2, PI/4);
              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);

              // арка
              halfpoints[0] := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
              halfpoints[0] := ModificatePoint(halfpoints[0]);
              for i := 10 to 9 do
              begin
                RotPoint := RotatePoint(aObject.ca1, aObject.ca2, I*AngleDelta);
                halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                halfpoints[i] := ModificatePoint(halfpoints[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
              Result.Add(Entity);
            end;
          end;
        end
        else
        begin // Зеркально
          if not aObject.LeftRight then //левосторонняя дверь
          begin
            if aObject.Opened then // если рисовать как открытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2);

              p1 :=aPoint3D(aObject.ca1.x, aObject.ca1.y,0);
              p1 := ModificatePoint(p1);


              RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -PI/2);
              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);

              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);
              // арка
              points[0] := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
              points[0] := ModificatePoint(points[0]);
              for i := 1 to 18 do
              begin
                RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -I*AngleDelta);
                points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                points[i] := ModificatePoint(points[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
              Result.Add(Entity);
            end
            else
            if aObject.HalfOpened then // если рисовать как полуоткрытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2);

              p1 :=aPoint3D(aObject.ca1.x, aObject.ca1.y,0);
              p1 := ModificatePoint(p1);


              RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -PI/4);
              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);

              // арка
              halfpoints[0] := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
              halfpoints[0] := ModificatePoint(halfpoints[0]);
              for i := 1 to 9 do
              begin
                RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -I*AngleDelta);
                halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                halfpoints[i] := ModificatePoint(halfpoints[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
              Result.Add(Entity);
            end;
          end
          else              // правосторонняя дверь
          begin
            if aObject.Opened then // если рисовать как открытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2);
              p1 :=aPoint3D(aObject.ca1.x, aObject.ca1.y,0);
              p1 := ModificatePoint(p1);


              RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -PI/2);
              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);

              {p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);}
              // арка
              points[0] := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
              points[0] := ModificatePoint(points[0]);
              for i := 1 to 18 do
              begin
                RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -I*AngleDelta);
                points[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                points[i] := ModificatePoint(points[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 19, @points[0], clBlack, False);
              Result.Add(Entity);
            end
            else
            if aObject.HalfOpened then // если рисовать как полуоткрытую дверь
            begin
              DoorAngle := GetRadOfLine(aObject.ca1, aObject.ca2);
              p1 :=aPoint3D(aObject.ca1.x, aObject.ca1.y,0);
              p1 := ModificatePoint(p1);


              RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -PI/4);
              p2 := aPoint3D(RotPoint.x, RotPoint.y,0);
              p2 := ModificatePoint(p2);
              Entity := Line_.create(p1, p2, 0);
              Result.Add(Entity);

              // арка
              halfpoints[0] := aPoint3D(aObject.ca2.x, aObject.ca2.y, 0);
              halfpoints[0] := ModificatePoint(halfpoints[0]);
              for i := 1 to 9 do
              begin
                RotPoint := RotatePoint(aObject.ca1, aObject.ca2, -I*AngleDelta);
                halfpoints[i] := aPoint3D(RotPoint.x, RotPoint.y,0);
                halfpoints[i] := ModificatePoint(halfpoints[i]);
              end;
              Entity := Polyline_.create(OCSAxis, 10, @halfpoints[0], clBlack, False);
              Result.Add(Entity);
            end;
          end;
        end;
      end;
      //
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TNetDoor', E.Message);
  end;
end;

function Write_TNetCol(aObject: TNetCol): DXF_Entity;
var
  i: integer;
  door: TnetDoor;
  p1, p2: point3D;
  Entity: DXF_Entity;
  OCS_Z: Point3D;
  points: array[0..3] of Point3D;
  ap1, ap2, ap3, ap4: TDoublePoint;
begin
  try
    Result := nil;
    OCS_Z := aPoint3D(0, 0, 1);
    aObject.GetPoints(ap1, ap2, ap3, ap4);
    points[0] := aPoint3D(ap1.x, ap1.y, 0);
    points[1] := aPoint3D(ap2.x, ap2.y, 0);
    points[2] := aPoint3D(ap3.x, ap3.y, 0);
    points[3] := aPoint3D(ap4.x, ap4.y, 0);
    points[0] := ModificatePoint(points[0]);
    points[1] := ModificatePoint(points[1]);
    points[2] := ModificatePoint(points[2]);
    points[3] := ModificatePoint(points[3]);
    Result := Polyline_.create(OCS_Z, 4, @points[0], 0, true);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TNetCol', E.Message);
  end;
end;

function Write_TPlanObject(aObject: TPlanObject): TList;
begin
  try
    Result := Write_TBlock(TFigureGrp(aObject));
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TPlanObject', E.Message);
  end;
end;

function Write_TPlanTrace(aObject: TPlanTrace): DXF_Entity;
begin
  try
    Result := nil;
    Result := Write_TLine(TLine(aObject));
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.Write_TPlanTrace', E.Message);
  end;
end;

procedure AddFiguresToLayer(aDXFLayer: DXF_Layer; aFigures: TList; LayerNbr: integer);
var
  i, j, k, ln: Integer;
  vFigure, InFigure: TFigure;
  Entity: DXF_Entity;
  EntityList: TList;
  EntAdd: boolean;
begin
  // Tolik -- 08/02/2017  --
  EntityList := nil;
  //
  try
    GLayerNumber := LayerNbr;
    for i := 0 to aFigures.Count - 1 do
    begin
      Entity := nil;
      // Tolik 08/02/2017 --
      //EntityList := nil;
      vFigure := TFigure(aFigures[i]);
      if vFigure.Visible then
      begin
        // Tolik -- 10/02/2017 --
        // тут все перепишем через else, чтоб ыбыстрее отработал цикл
        //
        if vFigure.ClassName = 'TLine' then
          Entity := Write_TLine(TLine(vFigure))
        else
        if vFigure.ClassName = 'TVertex' then
          Entity := Write_TVertex(TVertex(vFigure))
        else
        if vFigure.ClassName = 'TRectangle' then
          Entity := Write_TRectangle(TRectangle(vFigure))
        else
        if vFigure.ClassName = 'TCircle' then
          Entity := Write_TCircle(TCircle(vFigure))
        else
        if vFigure.ClassName = 'TPolyline' then
          Entity := Write_TPolyline(TPolyline(vFigure))
        else
        if vFigure.ClassName = 'TEllipse' then
          Entity := Write_TEllipse(TEllipse(vFigure))
        else
        if vFigure.ClassName = 'TArc' then
          Entity := Write_TArc(TArc(vFigure))
        else
        if vFigure.ClassName = 'TElpArc' then
          Entity := Write_TElpArc(TElpArc(vFigure))
        else
        if vFigure.ClassName = 'TText' then
          Entity := Write_TText(TText(vFigure))
        else
        if vFigure.ClassName = 'TRichText' then
          Entity := Write_TRichText(TRichText(vFigure))
        else
        if (vFigure.ClassName = 'THDimLine') or (vFigure.ClassName = 'TSCSHDimLine') then
          EntityList := Write_THDimLine(THDimLine(vFigure))
        else
        if (vFigure.ClassName = 'TVDimLine') or (vFigure.ClassName = 'TSCSVDimLine') then
          EntityList := Write_TVDimLine(TVDimLine(vFigure))
        else

        if vFigure.ClassName = 'TWMFObject' then
          Entity := Write_TWMFObject(TWMFObject(vFigure))
        else
        if vFigure.ClassName = 'TBMPObject' then
          Entity := Write_TBMPObject(TBMPObject(vFigure))
        else

        // БЛОКИ
        if (vFigure.ClassName = 'TFigureGrp') or (vFigure.ClassName = 'TBlock') or (vFigure.ClassName = 'TCadNorms') then
          EntityList := Write_TBlock(TFigureGrp(vFigure), 0, LayerNbr)
        else
        // Кабинеты
        if (vFigure.ClassName = 'TCabinet') then
          EntityList := Write_TCabinet(TCabinet(vFigure))
        else
        // Кабинеты
        if (vFigure.ClassName = 'TCabinetExt') then
          EntityList := Write_TCabinetExt(TCabinetExt(vFigure))
        else
        // TOrthoLine
        if (vFigure.ClassName = 'TOrthoLine') then
          EntityList := Write_TOrthoLine(TOrthoLine(vFigure))
        else
        // TConnectorObject
        if (vFigure.ClassName = 'TConnectorObject') then
          EntityList := Write_TConnectorObject(TConnectorObject(vFigure))
        else
        if (vFigure.ClassName = 'TSCSFigureGrp') then
          EntityList := Write_TSCSFigureGrp(TSCSFigureGrp(vFigure))
        else
        // TNet
        if (vFigure.ClassName = 'TNet') then
          EntityList := Write_TNet(TNet(vFigure))
        else
        // Схема проекта
        if (vFigure.ClassName = 'TPlanObject') then
          EntityList := Write_TPlanObject(TPlanObject(vFigure))
        else
        if (vFigure.ClassName = 'TPlanTrace') then
          Entity := Write_TPlanTrace(TPlanTrace(vFigure));

        // add entity
        if Entity <> nil then
        begin
          if Entity.SCS_Layer_Handle = 0 then
            aDXFLayer.add_entity_to_layer(Entity)
          else
          begin
            EntAdd := False;
            for ln := 0 to LayersList.Count - 1 do
            begin
              if DXF_Layer(LayersList[ln]).SCS_Layer_Handle = Entity.SCS_Layer_Handle then
              begin
                DXF_Layer(LayersList[ln]).add_entity_to_layer(Entity);
                EntAdd := True;
                break;
              end;
            end;
            if Not EntAdd then
              aDXFLayer.add_entity_to_layer(Entity)
          end;
        end
        else
        if EntityList <> nil then
        begin
          for j := 0 to EntityList.Count - 1 do
          begin
            Entity := DXF_Entity(EntityList[j]);
            if Entity.SCS_Layer_Handle = 0 then
              aDXFLayer.add_entity_to_layer(Entity)
            else
            begin
              EntAdd := False;
              for ln := 0 to LayersList.Count - 1 do
              begin
                if DXF_Layer(LayersList[ln]).SCS_Layer_Handle = Entity.SCS_Layer_Handle then
                begin
                  DXF_Layer(LayersList[ln]).add_entity_to_layer(Entity);
                  EntAdd := True;
                  break;
                end;
              end;
              if Not EntAdd then
                aDXFLayer.add_entity_to_layer(Entity)
            end;
          end;
          // Tolik -- 08/02/2017 --
          FreeAndNil(EntityList);
          //
        end;
      end;
    end;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.AddFiguresToLayer', E.Message);
  end;
  // Tolik -- 08/02/2017 -- на всякий --
  if EntityList <> nil then
    FreeAndNil(EntityList);
  //  
end;

var
	AcadPalette: HPALETTE;

const
	AcadColorTable: array [0..254] of TColor = (
		$FF,$FFFF,$FF00,$FFFF00,$FF0000,$FF00FF,$0,$4C4C4C,$A5A5A5,$FF,$7F7FFF,$A5,
		$5252A5,$7F,$3F3F7F,$4C,$26264C,$26,$131326,$3FFF,$7F9FFF,$29A5,$5267A5,$1F7F,
		$3F4F7F,$134C,$262F4C,$926,$131726,$7FFF,$7FBFFF,$52A5,$527CA5,$3F7F,$3F5F7F,
		$264C,$26394C,$1326,$131C26,$BFFF,$7FDFFF,$7CA5,$5291A5,$5F7F,$3F6F7F,$394C,
		$26424C,$1C26,$132126,$FFFF,$7FFFFF,$A5A5,$52A5A5,$7F7F,$3F7F7F,$4C4C,$264C4C,
		$2626,$132626,$FFBF,$7FFFDF,$A57C,$52A591,$7F5F,$3F7F6F,$4C39,$264C42,$261C,
		$132621,$FF7F,$7FFFBF,$A552,$52A57C,$7F3F,$3F7F5F,$4C26,$264C39,$2613,$13261C,
		$FF3F,$7FFF9F,$A529,$52A567,$7F1F,$3F7F4F,$4C13,$264C2F,$2609,$132617,$FF00,
		$7FFF7F,$A500,$52A552,$7F00,$3F7F3F,$4C00,$264C26,$2600,$132613,$3FFF00,$9FFF7F,
		$29A500,$67A552,$1F7F00,$4F7F3F,$134C00,$2F4C26,$92600,$172613,$7FFF00,$BFFF7F,
		$52A500,$7CA552,$3F7F00,$5F7F3F,$264C00,$394C26,$132600,$1C2613,$BFFF00,$DFFF7F,
		$7CA500,$91A552,$5F7F00,$6F7F3F,$394C00,$424C26,$1C2600,$212613,$FFFF00,$FFFF7F,
		$A5A500,$A5A552,$7F7F00,$7F7F3F,$4C4C00,$4C4C26,$262600,$262613,$FFBF00,$FFDF7F,
		$A57C00,$A59152,$7F5F00,$7F6F3F,$4C3900,$4C4226,$261C00,$262113,$FF7F00,$FFBF7F,
		$A55200,$A57C52,$7F3F00,$7F5F3F,$4C2600,$4C3926,$261300,$261C13,$FF3F00,$FF9F7F,
		$A52900,$A56752,$7F1F00,$7F4F3F,$4C1300,$4C2F26,$260900,$261713,$FF0000,$FF7F7F,
		$A50000,$A55252,$7F0000,$7F3F3F,$4C0000,$4C2626,$260000,$261313,$FF003F,$FF7F9F,
		$A50029,$A55267,$7F001F,$7F3F4F,$4C0013,$4C262F,$260009,$261317,$FF007F,$FF7FBF,
		$A50052,$A5527C,$7F003F,$7F3F5F,$4C0026,$4C2639,$260013,$26131C,$FF00BF,$FF7FDF,
		$A5007C,$A55291,$7F005F,$7F3F6F,$4C0039,$4C2642,$26001C,$261321,$FF00FF,$FF7FFF,
		$A500A5,$A552A5,$7F007F,$7F3F7F,$4C004C,$4C264C,$260026,$261326,$BF00FF,$DF7FFF,
		$7C00A5,$9152A5,$5F007F,$6F3F7F,$39004C,$42264C,$1C0026,$211326,$7F00FF,$BF7FFF,
		$5200A5,$7C52A5,$3F007F,$5F3F7F,$26004C,$39264C,$130026,$1C1326,$3F00FF,$9F7FFF,
		$2900A5,$6752A5,$1F007F,$4F3F7F,$13004C,$2F264C,$90026,$171326,$545454,$767676,
		$989898,$BABABA,$DCDCDC,$FFFFFF);

// Tolik -- 13/02/2017 --
{
function ColorToDxfColor(aColor: TColor): LongInt;
var f: TextFile;
begin

  AssignFile(f, 'd:\Color.txt');
  Append(f);
  try
    if aColor = 805306367 then
    begin
      Result := 7;
      Writeln(f, Inttostr(aColor) + ' == ' + Inttostr(Result));
    end
    else
    begin
      if aColor = 536870911 then
        aColor := 7;
      Result := GetNearestPaletteIndex(AcadPalette, ColorToRGB(aColor)) + 1;
      Writeln(f, Inttostr(aColor) + ' == ' + Inttostr(Result));
    end;
    CloseFile(f);
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.ColorToDxfColor', E.Message);
  end;

end;
}

function ColorToDxfColor(aColor: TColor): Integer;
begin
  try
    if aColor = 536870911 then
      aColor := 7;
  	Result := GetNearestPaletteIndex(AcadPalette, ColorToRGB(aColor)) + 1;
  except
    on E: Exception do AddExceptionToLogEx('U_ExportDXF.ColorToDxfColor', E.Message);
  end;
end;


//

var
	aLogPalette: PLogPalette;
	i: Integer;

initialization
	GetMem(aLogPalette, sizeof(TLogPalette) + 255 * sizeof(TPaletteEntry));
	try
		with aLogPalette^ do
		begin
			palVersion := $300;
			palNumEntries := 255;
			{$R-}
			for i := 0 to 254 do
				with palPalEntry[i] do
				begin
					peRed := GetRValue(AcadColorTable[i]);
					peGreen := GetGValue(AcadColorTable[i]);
					peBlue := GetBValue(AcadColorTable[i]);
					peFlags := 0;
				end;
			{$R+}
		end;

		AcadPalette := CreatePalette(aLogPalette^);
	finally
		FreeMem(aLogPalette, sizeof(TLogPalette) + 255 * sizeof(TPaletteEntry));
	end;
finalization
	DeleteObject(AcadPalette);
end.
