Отрисовка полилинии и сохранение в DXF

Discuss and ask questions about CAD VCL (Delphi and C++ Builder).

Moderators: SDS, support, admin

Post Reply
Rio
Posts: 9
Joined: 26 Dec 2006, 01:25
Location: Russia
Contact:

Отрисовка полилинии и сохранение в DXF

Post by Rio » 26 Dec 2006, 01:30

Имеются координаты типа:
743.9741 71.7737
743.9741 171.7737
643.9741 171.7737
643.9741 71.7737
743.9741 71.7737
вопрос:
Как произвести отрисовку на sgImage и сохранить
в DXF приведите пример пожалуйста.
с Уважением Алексей.

support
Posts: 3272
Joined: 30 Mar 2005, 11:36
Contact:

Post by support » 26 Dec 2006, 18:10

Доброго времени суток!

Мы предлагаем Вашему вниманию два способа сохранения в <b>DXF</b> формат:
<ul><li>Использование пакета <b>DXF Export VCL</b> (доступен по следующей ссылке: http://www.cadsofttools.com/download/dxfexportvcl.zip), при этом промежуточным звеном является метафайл <b>Windows</b>. Использование метафайла накладывает некоторые ограничения: сложные примитивы разбиваются на ряд простых, теряются блоки и слои.</li>
<li>Использование нового продукта, находящегося в стадии бета тестирования - <b>CAD to DXF Export</b> (доступен по следующей ссылке: http://www.cadsofttools.com/download/CADtoDXF.zip) Результирующий файл полностью соответствует <b>DXF</b> документации.</li></ul>
Следующий код показывает, как это реализовать. Добавляется прямоугольник и сохраняется в <b>DXF</b> файл:

<b>English</b>:

the question was how to add and to save Rectangle to <b>DXF</b> file format.

The answer is: here are two ways:

<ul><li>Usage of <b>DXF Export VCL</b> (available at: http://www.cadsofttools.com/download/dxfexportvcl.zip). Intermediate phase is <b>Windows</b> Metafile. There are some restrictions: complicated entities are split to rows of simple entities, blocks and layers are lost.</li>
<li>Usage of our new product - <b>CAD to DXF Export</b> (beta version is available at: http://www.cadsofttools.com/download/CADtoDXF.zip) Destination file is absolutely respective to <b>DXF</b> documentation.</li></ul>
The following demo adds rectangle and saves it to DXF file format:

<b>DXF Export VCL</b>:

Code: Select all

<b>uses</b>
  ... SGImage, DXFImage, DXFConv, sgConsts, DXFExport;

<b>type</b>
  TForm1 = <b>class</b>(TForm)
    ...
    btnSaveByMetafile: TButton;
    sgImage1: TsgImage;    
    OpenDialog1: TOpenDialog;
    procedure btnSaveByMetafileClick(Sender: TObject);    
  <b>private</b>
    <i><font color="blue">{ Private declarations }</font id="blue"></i>
    FImg: TsgDXFImage;

...

<b>procedure</b> TForm1.btnSaveByMetafileClick(Sender: TObject);
<b>var</b>
  vPoly: TsgDXFPolyline;
  vVertex: TsgDXFVertex;
  vMet: TMetafile;
  E: TsgDXFExport;
  vGr: TGraphic;
  vOffX, vOffY, vUSize: TsgFloat;
<b>begin
  if not</b> OpenDialog1.Execute <b>then</b>
    Exit;
  sgImage1.LoadFromFile(OpenDialog1.FileName);
  <b>if</b> sgImage1.Picture.Graphic <b>is</b> TsgDXFImage <b>then
  begin</b>
    sgImage1.Align := alClient;
    FImg := TsgDXFImage(sgImage1.Picture.Graphic);
  <b>end
  else
  begin</b>
    FImg := <b>nil</b>;
    Exit;
  <b>end</b>;

  vPoly := TsgDXFPolyline.Create;

  vVertex := TsgDXFVertex.Create;
  vVertex.Point := MakeFPoint(<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">);
  vPoly.AddEntity(vVertex);

  vVertex := TsgDXFVertex.Create;
  vVertex.Point := MakeFPoint(<font color="blue">1000</font id="blue">,<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">);
  vPoly.AddEntity(vVertex);

  vVertex := TsgDXFVertex.Create;
  vVertex.Point := MakeFPoint(<font color="blue">1000</font id="blue">,<font color="blue">1000</font id="blue">,<font color="blue">0</font id="blue">);
  vPoly.AddEntity(vVertex);

  vVertex := TsgDXFVertex.Create;
  vVertex.Point := MakeFPoint(<font color="blue">0</font id="blue">,<font color="blue">1000</font id="blue">,<font color="blue">0</font id="blue">);
  vPoly.AddEntity(vVertex);
  vPoly.Closed := True;

  FImg.Converter.Layouts[<font color="blue">0</font id="blue">].AddEntity(vPoly);
  <b>if</b> Assigned(FImg.Converter.OnCreate) <b>then</b>
    FImg.Converter.OnCreate(vPoly);
  FImg.Converter.Loads(vPoly);

  FImg.GetExtents;
  sgImage1.Refresh;

  vGr := sgImage1.Picture.Graphic;
  E := TsgDXFExport.Create;
  <b>try</b>
    E.IsParseWhite := True;
    <b>if not</b> ((vGr <b>is</b> TsgDXFImage) <b>or</b> (vGr <b>is</b> TMetafile)) <b>then
    begin</b>
      ShowMessage(<font color="blue">'Raster drawings can not be saved to DXF format'</font id="blue">);
      Exit;
    <b>end
    else
    begin
      if not</b> (vGr <b>is</b> TsgDXFImage) <b>then
      begin</b>
        E.Use01MM := False;
        E.Canvas.StretchDraw(Rect(0, 0, vGr.Width, vGr.Height), vGr);
        E.EndDraw;
      <b>end
      else
      begin</b>
        vMet := TsgDXFImage(vGr).ExportToMetafile(vOffX, vOffY, vUSize);
        DXFExport.OffsetX := vOffX;
        DXFExport.OffsetY := vOffY;
        E.UnitSize := vUSize;
        E.LoadFromMetafile(vMet);
        vMet.Free;
      <b>end</b>;
    <b>end</b>;
    E.SaveToFile(<font color="blue">'c:\SaveByMetafile.dxf'</font id="blue">);
  <b>finally</b>
    E.Free;
  <b>end</b>;
<b>end</b>;
<b>CAD to DXF Export</b>:

Code: Select all

<b>uses</b>
  ... SGImage, DXFImage, DXFConv, sgConsts, CADtoDXF;

<b>type</b>
  TForm1 = <b>class</b>(TForm)
    ...    
    sgImage1: TsgImage;
    btnSaveDirectly: TButton;
    OpenDialog1: TOpenDialog;    
    <b>procedure</b> btnSaveDirectlyClick(Sender: TObject);
  <b>private</b>
    <i><font color="blue">{ Private declarations }</font id="blue"></i>
    FImg: TsgDXFImage;

...

<b>procedure</b> TForm1.btnSaveDirectlyClick(Sender: TObject);
<b>const</b>
  cnstLayerName: <b>string</b> = <font color="blue">'new_Layer'</font id="blue">;
  cnstLTypeName: <b>string</b> = <font color="blue">'new_LType'</font id="blue">;
<b>var</b>
  vPoly: TsgDXFPolyline;
  vVertex: TsgDXFVertex;
  vCADFile: TsgDXFImage;
  vLType: TsgDXFLineType;
  vExp: TsgCADtoDXF;
<b>begin</b>
  vCADFile := TsgDXFImage.Create;
  <b>try</b>
    vCADFile.Converter.InitializeSections;
    <i><font color="blue">{ Adding the new linetype to image-converter }</font id="blue"></i>
    vLType := TsgDXFLineType.Create;
    vLType.Name := cnstLTypeName;
    vLType.Lines.AddTick(<font color="blue">25</font id="blue">);      <font color="blue"><i>// length of the "solid" part of a line </i> </font id="blue">
    vLType.Lines.AddTick(<font color="blue">-12.5</font id="blue">);    <font color="blue"><i>// length of the "empty" part of a line </i></font id="blue">
    vCADFile.Converter.Sections[csLTypes].AddEntity(vLType);

    <i><font color="blue">{ Adding the polyline entity }</font id="blue"></i>
    vPoly := TsgDXFPolyline.Create;

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">);
    vPoly.AddEntity(vVertex);

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(<font color="blue">1000</font id="blue">,<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">);
    vPoly.AddEntity(vVertex);

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(<font color="blue">1000</font id="blue">,<font color="blue">1000</font id="blue">,<font color="blue">0</font id="blue">);
    vPoly.AddEntity(vVertex);

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(<font color="blue">0</font id="blue">,<font color="blue">1000</font id="blue">,<font color="blue">0</font id="blue">);
    vPoly.AddEntity(vVertex);
    vPoly.Closed := True;
    vPoly.SetColor(clBlue);                                      <font color="blue"><i>// color </i></font id="blue">
    vPoly.Layer := vCADFile.Converter.LayerByName(cnstLayerName);<font color="blue"><i>// Layer will be created automatically </i></font id="blue">
    vPoly.SetLType(vCADFile.Converter.LTypeByName(cnstLTypeName));
    <b>if</b> Assigned(vCADFile.Converter.OnCreate) <b>then</b>
      vCADFile.Converter.OnCreate(vPoly);
    vCADFile.Converter.Loads(vPoly);
    vCADFile.Converter.Sections[csEntities].AddEntity(vPoly);

    <i><font color="blue">{ Apply new drawing extents }</font id="blue"></i>
    vCADFile.GetExtents;

    <font color="blue"><i>{ Copying new drawing to the sgPaintBox } </i></font id="blue">
    sgImage1.Picture.Graphic := vCADFile;
    sgImage1.Align := alClient;
    FImg := TsgDXFImage(sgImage1.Picture.Graphic);
    sgImage1.Width := Round(vCADFile.AbsWidth);
    sgImage1.Height := Round(vCADFile.AbsHeight);
    sgImage1.Invalidate;
    vExp := TsgCADtoDXF.Create(TsgDXFImage(sgImage1.Picture.Graphic));
    vExp.Version := acR2000;
    vExp.SaveToFile(<font color="blue">'c:\SaveDirectly.dxf'</font id="blue">);
    vExp.Free;
  <b>finally</b>
    vCADFile.Free;
  <b>end</b>;
<b>end</b>;
Sergey.

please post questions to the forum or write to support@cadsofttools.com

Rio
Posts: 9
Joined: 26 Dec 2006, 01:25
Location: Russia
Contact:

Post by Rio » 28 Dec 2006, 19:14

Неужели, чтобы нарисовать полилинию или полигон
каждую точку так надо описывать:

Code: Select all

{ Adding the polyline entity }
    vPoly := TsgDXFPolyline.Create;

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(0,0,0);
    vPoly.AddEntity(vVertex);

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(1000,0,0);
    vPoly.AddEntity(vVertex);

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(1000,1000,0);
    vPoly.AddEntity(vVertex);

    vVertex := TsgDXFVertex.Create;
    vVertex.Point := MakeFPoint(0,1000,0);
    vPoly.AddEntity(vVertex);
    vPoly.Closed := True;
неужели так громоздко, или я неправильно понял?
Нельзя ли в цикле (координаты берутся из Stringgrid'a)
показать самый простой вариант?

Rio
Posts: 9
Joined: 26 Dec 2006, 01:25
Location: Russia
Contact:

Post by Rio » 28 Dec 2006, 19:31

Насчёт громоздкости, я загнул :)
,извиняюсь сам не разобрался, с циклом понятно, но
это ведь каждый раз создаётся линия и в итоге при нажатии в Автокаде
на сведения объект "разбитый" на несколько отрезков,
CadtoDxf так сохраняет или нет.
С Уважением Алексей.

PoltP
Posts: 8
Joined: 20 Jul 2006, 12:47
Location: Russia
Contact:

Post by PoltP » 29 Dec 2006, 12:05

Для задания POLYLINE в DXF необходимо описать каждую вершину (VERTEX) - таков уж формат DXF.
Заметим, что VERTEX - это не просто "точка" (!), здесь могут также храниться данные о Start/Endwidth, Bulge (задаёт дугу) или Polyface vertex indexes (индекс вершин POLYFACE), о чём подробнее Вы можете почитать в документации по CADImportVCL (см. описание TsgDXFVertex и TsgDXFPolyline).
<blockquote id="quote"><font size="2" face="Verdana, Arial, Helvetica" id="quote">quote:<hr height="1" noshade id="quote">это ведь каждый раз создаётся линия и в итоге при нажатии в Автокаде на сведения объект "разбитый" на несколько отрезков<hr height="1" noshade id="quote"></font id="quote"></blockquote id="quote">
Поясните это подробнее, что Вы имеете ввиду?
<blockquote id="quote"><font size="2" face="Verdana, Arial, Helvetica" id="quote">quote:<hr height="1" noshade id="quote">CadtoDxf так сохраняет или нет.<hr height="1" noshade id="quote"></font id="quote"></blockquote id="quote">
CADtoDXF в текущей версии сохраняет POLYLINE как 3dPolyline, а DXFExport как LWPOLYLINE.
DXFExport вообще изначально был ориентирован на экспорт из метафайла, поэтому его возможности по прямому экспорту достаточно скудны. Мы рекомендуем Вам рассматривать далее именно CADtoDXF, так как этот продукт обещает предоставлять достаточно широкий спектр возможностей по созданию DXF-файлов и будет постоянно совершенствоваться.

- - -
Yours faithfully,
Pavel Poltavets,
senior developer Soft Gold Ltd.

Rio
Posts: 9
Joined: 26 Dec 2006, 01:25
Location: Russia
Contact:

Post by Rio » 30 Dec 2006, 01:21

Я имел ввиду то, что
при выводе сведений об объекте
(площадь, координаты, периметр).
Данные по нарисованой в Автокаде полилинии
такие:
LWPOLYLINE Layer: "0"
Space: Model space
Handle = 81
Closed
Constant width 0.0000
area 207623.0915
perimeter 1917.3910

at point X= 272.7671 Y= 732.3982 Z= 0.0000
at point X= 848.5099 Y= 496.2553 Z= 0.0000
at point X= 450.4655 Y= 245.9083 Z= 0.0000
at point X= 143.0472 Y= 251.2348 Z= 0.0000
at point X= 191.0258 Y= 648.9492 Z= 0.0000
, а сохранённые из CaDtoDxf полилиния разбитая на отрезки,
то есть я не могу узнать площадь, периметр.
Нужен такой же формат (см.выше), а получается такой:
POLYLINE Layer: "new_Layer"
Space: Model space
Color: 5 (blue) Linetype: "new_LType"
Handle = 19
Closed space
First 3 points did not define a plane. No area calculated.
perimeter 0.0000

VERTEX Layer: "0"
Space: Model space
Color: 5 (blue) Linetype: "BYLAYER"
Handle = 1a
Space
at point, X= 120.0000 Y= 100.0000 Z= 0.0000

VERTEX Layer: "0"
Space: Model space
Color: 5 (blue) Linetype: "BYLAYER"
Handle = 1b
Space
at point, X= 121.0000 Y= 101.0000 Z= 0.0000
Press ENTER to continue:

VERTEX Layer: "0"
Space: Model space
Color: 5 (blue) Linetype: "BYLAYER"
Handle = 1c
Space
at point, X= 122.0000 Y= 102.0000 Z= 0.0000

END SEQUENCE Layer: "0"
Space: Model space
Handle = 1d

Rio
Posts: 9
Joined: 26 Dec 2006, 01:25
Location: Russia
Contact:

Post by Rio » 30 Dec 2006, 01:29

То есть, например в компоненте TCaD (от китайских разработчиков)
сохранение всей рабочей области
происходит всего одной процедурой SaveFileDXF(const filename:string)
очень просто;
Причём всё нарисованое сохраняется так, как будто я всё рисовал в Автокаде без изменений, есть ли в CaDtoDXF подобное.
Меня интересует конкретно отрисовка (easy) примитивов, а конкретно полилинии в 2D из
своих координат, распечатка в масштабе и сохранение в DXF.
Приведите примеры по этим темам пожалуйста.
С Наступающим 2007 годом.
С Уважением Алексей.

PoltP
Posts: 8
Joined: 20 Jul 2006, 12:47
Location: Russia
Contact:

Post by PoltP » 04 Jan 2007, 16:28

<blockquote id="quote"><font size="2" face="Verdana, Arial, Helvetica" id="quote">quote:<hr height="1" noshade id="quote"> Я имел ввиду то, что при выводе сведений об объекте
(площадь, координаты, периметр).
Данные по нарисованой в Автокаде полилинии такие:
...<hr height="1" noshade id="quote"></font id="quote"></blockquote id="quote">
Проблема ясна, для 3dPolyline AutoCAD (TM) не показывает площадь и периметр.
Повторюсь, CADtoDXF в текущей версии сохраняет POLYLINE как 3dPolyline, а DXFExport как LWPOLYLINE. Так как CADtoDXF базируется на иерархии классов из CADImportVCL, в котором POLYLINE сделан в общем виде (как трехмерный 3dPolyline), то такой неприятный эффект, как сохранение POLYLINE в трехмерном виде удастся устранить только после корректировки дерева наследования примитивов в CADImportVCL. Мы обязательно планируем решать данную задачу, однако здесь не можем указать сроки ее решения, в силу нетривиальности постановки.

<blockquote id="quote"><font size="2" face="Verdana, Arial, Helvetica" id="quote">quote:<hr height="1" noshade id="quote">То есть, например в компоненте TCaD (от китайских разработчиков) сохранение всей рабочей области
происходит всего одной процедурой SaveFileDXF(const filename:string)
очень просто;
Причём всё нарисованое сохраняется так, как будто я всё рисовал в Автокаде без изменений, есть ли в CaDtoDXF подобное.
Меня интересует конкретно отрисовка (easy) примитивов, а конкретно полилинии в 2D из своих координат, распечатка в масштабе и сохранение в DXF.
Приведите примеры по этим темам пожалуйста.
С Наступающим 2007 годом.
<hr height="1" noshade id="quote"></font id="quote"></blockquote id="quote">
Вы имеете ввиду сохранение отсеченной области?
То есть Вы, например, выделяете прямоугольником область на чертеже и хотите сохранить эту часть в DXF или сохранить в DXF видимую на экране часть чертежа как это сделано в нашем продукте ABViewer (http://www.cadsofttools.com/en/products/abviewer.html). Если так, то в CADtoDXF пока такой возможности нет, эта функция доступна в DXFExportVCL, но только при экспорте метафайла (предварительно в нем задается регион отсечения).
Спасибо за поздравление. Вас также с Новым Годом.

- - -
Yours faithfully,
Pavel Poltavets,
senior developer Soft Gold Ltd.

Post Reply