unit Unit1;
{$INCLUDE CADSoftTools.INC}
//If you see the error "File not found: 'CADSoftTools.INC'",
//then please contact info@cadsofttools.com to get a compilable version.
//If you have a compilable version, you need to copy the contents of
// Lib7/LibXE5win32/LibXE5win64... to Lib directory according to your
// Delphi version and target CPU platform.

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, CADImage, DXFConv,sgConsts, sgFunction, DWG, DWG12, DXF,
  CGM, HPGL2, SVG, ExtCtrls,
  {$IFDEF DEMO}
  fInfo,
  {$ENDIF}

  ExtDlgs;

type
  TForm1 = class(TForm)
    ReadDWG: TButton;
    LoadFile: TButton;
    ReadLineData: TButton;
    Image1: TImage;
    OpenPictureDialog1: TOpenPictureDialog;
    ChangeLayers: TButton;
    ReadTexts: TButton;
    ReadBlockAttributes: TButton;
    CopyToBMP: TButton;
    AddChangeDelete: TButton;
    AddEntities: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    ColorToLineweight: TButton;
    Label4: TLabel;
    Label5: TLabel;
    AddHatch: TButton;
    AddLine: TButton;
    AddXRef: TButton;
    CalculateTexts: TButton;
    FindBlock: TButton;
    RotateDrawing: TButton;
    LayerInformation: TButton;
    procedure ReadDWGClick(Sender: TObject);
    procedure LoadFileClick(Sender: TObject);
    procedure ReadLineDataClick(Sender: TObject);
    procedure ChangeLayersClick(Sender: TObject);
    procedure ReadTextsClick(Sender: TObject);
    procedure ReadBlockAttributesClick(Sender: TObject);
    procedure CopyToBMPClick(Sender: TObject);
    procedure AddChangeDeleteClick(Sender: TObject);
    procedure AddEntitiesClick(Sender: TObject);
    procedure ColorToLineweightClick(Sender: TObject);
    procedure AddHatchClick(Sender: TObject);
    procedure AddLineClick(Sender: TObject);
    procedure AddXRefClick(Sender: TObject);
    procedure CalculateTextsClick(Sender: TObject);
    procedure FindBlockClick(Sender: TObject);
    procedure RotateDrawingClick(Sender: TObject);
    procedure LayerInformationClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Types;

{$R *.dfm}

procedure TForm1.ReadDWGClick(Sender: TObject);
var
  vDrawing: TsgDWGImage; //TsgDWGImage class is used only for reading DWG.
 // To read other formats use the corresponding classes.
  // E.g. for DXF: TsgCADdxfImage, for PLT/HPGL: TsgHPGLImage.

begin
  vDrawing := TsgDWGImage.Create;
  vDrawing.LoadFromFile('Gasket.dwg');
  Image1.Canvas.Draw(0, 0, vDrawing);
  vDrawing.Free;
  // Zooming and panning of the drawing are implemented in the demo Viewer
  // via a special viewing control TsgDrawingNavigator
end;

procedure TForm1.LoadFileClick(Sender: TObject);
var
  // Delphi TPicture object works with CAD files when
  // CAD Import VCL libraries are in the section uses
  vPicture: TPicture;
  vRect: TRect; // vRect is used to calculate the drawing visualization rectangle
  vRatioW, vRatioH: double;
begin
  // Path to shx fonts
  sSHXSearchPaths := ExpandFileName('../../../SHX');
  vPicture := TPicture.Create;
  if OpenPictureDialog1.Execute then
    vPicture.LoadFromFile(OpenPictureDialog1.FileName);

  //Calculation of the drawing visualization rectangle
  //  vPicture.Graphic stores CAD graphic if you open DWG, DXF, PLT or
  // other supported CAD extensions
  vRect := Image1.ClientRect;
  vRatioW := vRect.Right/vPicture.Graphic.Width;
  vRatioH := vRect.Bottom/vPicture.Graphic.Height;
  if (vRatioW > vRatioH) then
    vRect.Right := Round(vPicture.Graphic.Width * vRatioH)
  else
    vRect.Bottom := round(vPicture.Graphic.Height * vRatioW);
  Image1.Picture := nil; // clearing of the image
  Image1.Canvas.StretchDraw(vRect, vPicture.Graphic);
end;

procedure TForm1.ReadLineDataClick(Sender: TObject);
var
  vDrawing: TsgCADDXFImage; // Class for DXF format reading
  I: Integer;
  // "DXF" is used in the name of the class Line for compatibility
  // Uses this class for lines in all CAD formats
  vLine: TsgDXFLine;
begin
  vDrawing := TsgCADDXFImage.Create; //TsgDXFImage - class for DXF file reading
  vDrawing.LoadFromFile('Entities.dxf');
// Search of entities in the current layout of the drawing
  for I := 0 to vDrawing.CurrentLayout.Count - 1 do
  begin
    if vDrawing.CurrentLayout.Entities[I].EntType = ceLine then
    begin
      vLine := TsgDXFLine(vDrawing.CurrentLayout.Entities[I]);
      ShowMessage('Line is found. Handle = ' +  IntToStr(vLine.Handle) +
        '; X: ' + FloatToStr(vLine.Point.X) + '; Y: ' +  FloatToStr(vLine.Point.Y) +
        '; X1: ' + FloatToStr(vLine.Point1.X) +  '; Y1: ' +  FloatToStr(vLine.Point1.Y));
      break;
    end;
  end;
  vDrawing.Free;
end;

procedure TForm1.CalculateTextsClick(Sender: TObject);
var
  vDrawing: TsgCADImage;
  I, vCount: Integer;
  vPicture: TPicture;
begin
  vPicture := TPicture.Create;
  if OpenPictureDialog1.Execute then
    vPicture.LoadFromFile(OpenPictureDialog1.FileName)
  else
    Exit;
  if not (vPicture.Graphic is TsgCADImage) then // Checks that this is the CAD drawing
    Exit;
  vDrawing := TsgCADImage(vPicture.Graphic);
  vCount := 0;
  for I := 0 to vDrawing.Converter.Counts[csEntities] - 1 do
    if vDrawing.Entities[I] is TsgDXFText then
      Inc(vCount);
  ShowMessage(Format('There are %d text entities in the drawing', [vCount]));
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
  vDrawing.Free;
end;

procedure TForm1.ChangeLayersClick(Sender: TObject);
var
  vDrawing: TsgCADDXFImage;
  vLayer: TsgDXFLayer; // Class for Layers
begin
  vDrawing := TsgCADDXFImage.Create;
  vDrawing.LoadFromFile('Entities.dxf');
  // Changes color of Layer '0'
  vDrawing.Converter.LayerByName('0').Color := clRed;
  // If layer2 doesn't exist, a new layer will be created
  vLayer := vDrawing.Converter.LayerByName('Layer2');
  vLayer.Visible := False; //Changes layer visibility
  Image1.Picture.Graphic := nil;
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
  vDrawing.Free;
end;

procedure TForm1.ReadTextsClick(Sender: TObject);
var
  vDrawing: TsgCADDXFImage; // Class for DXF format reading
  I, J: Integer;
  // "DXF" is used in the name of the class Line for compatibility
  // Uses this class for lines in all CAD formats
  vText: TsgDXFText;
  vMText: TsgDXFMText;
  S: string;
begin
  vDrawing := TsgCADDXFImage.Create; //TsgDXFImage - class for DXF file reading
  vDrawing.LoadFromFile('Entities.dxf');
  Image1.Picture.Graphic := nil;
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
// Search of entities in the current layout of the drawing
  for I := 0 to vDrawing.CurrentLayout.Count - 1 do
  begin
    if vDrawing.CurrentLayout.Entities[I] is TsgDXFText then
    begin
      vText := TsgDXFText(vDrawing.CurrentLayout.Entities[I]);
      ShowMessage('Text: ' + #13 + vText.Text);
    end;
    if vDrawing.CurrentLayout.Entities[I]is TsgDXFMText then
    begin
      vMText := TsgDXFMText(vDrawing.CurrentLayout.Entities[I]);
      for J := 0 to vMText.Block.Count - 1 do
        S := S + TsgDXFText(vMText.Block.Entities[J]).Text + #13;
      ShowMessage('MText: ' + #13 + S);
    end;
  end;
  vDrawing.Free;
end;

procedure TForm1.RotateDrawingClick(Sender: TObject);
var
  vDrawing: TsgCADImage;
begin
  vDrawing := TsgCADDXFImage.Create;
  vDrawing.LoadFromFile('Entities.dxf');
  vDrawing.Rotate(axisZ, 90); // Rotates 90%
  vDrawing.GetExtents; // Recalculates the extents of the drawing
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
  vDrawing.Free;
end;

procedure TForm1.ReadBlockAttributesClick(Sender: TObject);
var
  vDrawing: TsgCADDXFImage; // class for DXF format reading
  I, J: Integer;
  // "DXF" in the name of the class Line is used for compatibility
  // Uses this class for lines in all CAD formats

  // Insert is a block referense. Many inserts can refer to one block.
  vInsert: TsgDXFInsert;
  S: string;
begin
  vDrawing := TsgCADDXFImage.Create; //TsgDXFImage - class for DXF file reading
  vDrawing.LoadFromFile('Entities.dxf');
// Search of entities in the current layout of the drawing
  for I := 0 to vDrawing.CurrentLayout.Count - 1 do
  begin
    if vDrawing.CurrentLayout.Entities[I].EntType = ceInsert then
    begin
      vInsert := TsgDXFInsert(vDrawing.CurrentLayout.Entities[I]);
      for  J := 0 to vInsert.Attribs.Count - 1 do
        S := S + TsgDXFAttrib(vInsert.Attribs[J]).Tag + ' = ' +
          TsgDXFAttrib(vInsert.Attribs[J]).Value + #13;
      ShowMessage('Block name: ' + #13 + vInsert.Block.Name + #13 + S);
    end;
    S := '';
  end;
  vDrawing.Free;
end;

procedure TForm1.CopyToBMPClick(Sender: TObject);
var
  vPicture: TPicture;
  vBitmap: TBitmap;
begin
  vPicture := TPicture.Create;
  if OpenPictureDialog1.Execute then
    vPicture.LoadFromFile(OpenPictureDialog1.FileName);
  vBitmap := TBitmap.Create;
  vBitmap.Width := 1000; // The bitmap will have 1000 px width, height will be calulated automatically.
  vBitmap.Height := Round( vBitmap.Width * (vPicture.Graphic.Height / vPicture.Graphic.Width));
  vBitmap.Canvas.StretchDraw(Rect(0, 0, vBitmap.Width, vBitmap.Height) , vPicture.Graphic);
  vBitmap.SaveToFile(OpenPictureDialog1.FileName + '.bmp');
  ShowMessage('File is saved to BMP: ' + OpenPictureDialog1.FileName + '.bmp');
  vBitmap.Free;
end;

procedure TForm1.FindBlockClick(Sender: TObject);
var
  vDrawing: TsgCADdxfImage; //Requires the "DXF" unit added to the clause "uses"
  I: Integer;
  BlockName: string;
begin
  vDrawing := TsgCADDXFImage.Create; //TsgDXFImage - class for DXF file reading
  vDrawing.LoadFromFile('Entities.dxf');
  BlockName := 'Block1'; //The block name is  Block1
  for I := 0 to vDrawing.Converter.Counts[csBlocks] - 1 do
    if Lowercase(vDrawing.Blocks[I].Name) = Lowercase(BlockName) then
    begin //found
      ShowMessage(Format('Block with name "%s" has found.' + #13#10 +
        'Index of the block is %d', [BlockName, I]));
      Break;
    end;
  vDrawing.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  sSHXSearchPaths := ExpandFileName('../../../SHX');
  {$IFDEF DEMO}
  fInfo.CreateInfoFrame(Handle, Point(170, 110));
  {$ENDIF}
end;

procedure TForm1.AddChangeDeleteClick(Sender: TObject);
var
  vDrawing: TsgCADDXFImage; // Class for DXF format reading
  vLine: TsgDXFLine;
begin
  vDrawing := TsgCADDXFImage.Create;
  vDrawing.LoadFromFile('Entities.dxf');
  // Changes color
  vDrawing.CurrentLayout.Entities[1].Color := clBlue;
  vDrawing.CurrentLayout.Entities[1].LineWeight := 2;
  //Deletes the circle entity from Entities.dxf
  vDrawing.CurrentLayout.RemoveEntity(vDrawing.CurrentLayout.Entities[2]);
  // Adds a line
  vLine := TsgDXFLine.Create;
  // Point has 3 floating values: x, y, z
  vLine.Point := MakeFPoint(50, 0, 0);
  vLine.Point1 := MakeFPoint(50, 70, 10);
  vLine.LineWeight := 1; // 1 mm
  //Adds the line to the drawing database:
  vDrawing.Converter.Loads(vLine);
  //Adds the line to the current layout:
  vDrawing.CurrentLayout.AddEntity(vLine);
  vDrawing.GetExtents; // Recalculates the extents of the drawing
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
  vDrawing.Free;
end;

procedure TForm1.AddEntitiesClick(Sender: TObject);
var
  vDrawing: TsgCADImage;
  vLayer: TsgDXFLayer;
  vCircle: TsgDXFCircle;
  vLine: TsgDXFLine;
  vPoly: TsgDXFLWPolyline;
  vVertex: TsgDXFVertex;
  vText: TsgDXFText;
begin
// Creatng a new drawing structure
  vDrawing := TsgCADImage.Create();
  vDrawing.Converter.InitializeSections();
  vDrawing.CurrentLayout := vDrawing.Layouts[0];
// Creating a new layer
  vLayer := TsgDXFLayer.Create;
  vLayer.Name := 'Line';
  vLayer.Color := $7F9FFF;
  vLayer.LineWeight := 2;
// Adding a new layer to the drawing
  vDrawing.Converter.Loads(vLayer);
  vDrawing.Converter.Sections[csLayers].AddEntity(vLayer);
// Creating a new circle entity
  vCircle := TsgDXFCircle.Create();
  vCircle.Color := clRed;
  vCircle.Point := MakeFPoint(100, 100, 0);
  vCircle.Radius := 50;
// Adding a new entity to the drawing
  vDrawing.Converter.Loads(vCircle);
  vDrawing.CurrentLayout.AddEntity(vCircle);
// Creating a line
  vLine := TsgDXFLine.Create;
  vLine.Point := MakeFPoint(0, 0, 0);
  vLine.Point := MakeFPoint(100, 100, 0);
  vLine.Layer := vLayer; // Line takes color and lineweight from the layer
  vDrawing.Converter.Loads(vLine);
  vDrawing.CurrentLayout.AddEntity(vLine);
// Creating a 2d polyline
  vPoly := TsgDXFLWPolyline.Create;
  vPoly.Closed := True;
  vVertex := TsgDXFVertex.Create; // Vertexes are points of the polyline
  vVertex.Point := MakeFPoint(0, 300, 0);
  vPoly.AddEntity(vVertex);
  vVertex := TsgDXFVertex.Create;
  vVertex.Point := MakeFPoint(250, 300, 0);
  vVertex.Bulge := 0.5; //Arc segment
  vPoly.AddEntity(vVertex);
  vVertex := TsgDXFVertex.Create;
  vVertex.Point := MakeFPoint(250, 0, 0);
  vPoly.AddEntity(vVertex);
  vPoly.ColorCAD := MakeColorCAD(acIndexColor,5); // AutoCAD index color
  vDrawing.Converter.Loads(vPoly);
  vDrawing.CurrentLayout.AddEntity(vPoly);
// Creating text
  vText := TsgDXFText.Create;
  vText.Text  := 'CAD Import VCL examples';
  vText.Point := MakeFPoint(10, 280, 0);
  vText.Height := 10;
  vText.Color := clTeal;
  vDrawing.Converter.Loads(vText);
  vDrawing.CurrentLayout.AddEntity(vText);
  // Recalculation of the drawing extents
  vDrawing.GetExtents();
//------------------
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
  vDrawing.Free;
// See the demo AddEntities to find the examples about adding other entities and structures
end;

procedure TForm1.AddHatchClick(Sender: TObject);
var
  vDrawing: TsgCADDXFImage; // Class for DXF format reading
  vHatch: TsgCADCurvePolygon;
  vBoundaryList: Tsg2DBoundaryList;
  vPoly: Tsg2DPolyline;
begin
  // Adding hatch - a green triangle at the top of the drawing
  vDrawing := TsgCADDXFImage.Create;
  vDrawing.LoadFromFile('Entities.dxf');
  vHatch := TsgCADCurvePolygon.Create;
  vDrawing.CurrentLayout.AddEntity(vHatch);
  vHatch.SetColor(clGreen);
  vBoundaryList := vHatch.AddBoundaryList(7);
  vPoly := Tsg2DPolyline.Create;
  vBoundaryList.Add(vPoly);
  vPoly.Closed := True;
  vPoly.AddVertex(MakeF2DPoint(100, 100));
  vPoly.AddVertex(MakeF2DPoint(100, 150));
  vPoly.AddVertex(MakeF2DPoint(200, 125));
  vDrawing.Converter.Loads(vHatch);
  vDrawing.GetExtents;
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
end;

procedure TForm1.AddLineClick(Sender: TObject);
var
  vDrawing: TsgCADImage;
  vLine: TsgDXFLine;
begin
  vDrawing := TsgCADDXFImage.Create;
  vDrawing.LoadFromFile('Entities.dxf');
  // Adds a vertical blue line
  vLine := TsgDXFLine.Create;
  // Point has 3 floating values: x, y, z
  vLine.Point := MakeFPoint(50, 0, 0);
  vLine.Point1 := MakeFPoint(50, 70, 10);
  vLine.LineWeight := 1; // 1 mm
  vLine.Color := clBlue;
  //Adds the line to the drawing database
  vDrawing.Converter.Loads(vLine);
  //Adds the line to the current layout for displaying:
  vDrawing.CurrentLayout.AddEntity(vLine);
  vDrawing.GetExtents; // Recalculates the extents of the drawing
  Image1.Canvas.StretchDraw(Rect(0, 0,
    Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
  vDrawing.Free;
end;

procedure TForm1.AddXRefClick(Sender: TObject);
var
  vCADFile, vCADContainer: TsgCADImage; //The "DXF" and "DWG" units are required to be added to the clause "uses"
  Pos, Scale: TFPoint;//The "DXFConv" unit is required to be added to the clause "uses"
begin
  vCADContainer := TsgCADdxfImage.Create;
  try
    vCADContainer.LoadFromFile('Entities.dxf'); // Base file
    Pos.X := 10.5;//X drawing position (in AutoCAD units)
    Pos.Y := -12.23;//Y drawing position (in AutoCAD units)
    Pos.Z := 0;//Z drawing position (in AutoCAD units)
    Scale.X := 2;// zoom x 2
    Scale.Y := 1;// no zoom
    Scale.Z := 1;;// no zoom
    vCADFile := TsgCADDXFImage.Create;
    vCADFile.IsWithoutBorder := True;
    vCADFile.LoadFromFile('Entities.dxf'); // The second file
    vCADContainer.AddScaledDXF(vCADFile, 'XREF1', Pos, Scale, 0);
    Pos.X := 50;//X drawing position (in AutoCAD units)
    Pos.Y := 100;//Y drawing position (in AutoCAD units)
    Pos.Z := 0;//Z drawing position (in AutoCAD units)
    Scale.X :=  0.5;// zoom x 0.5
    Scale.Y :=  0.5;// zoom x 0.5
    Scale.Z := 1;
    vCADFile := TsgDWGImage.Create;
    vCADFile.IsWithoutBorder := True;
    vCADFile.LoadFromFile('Gasket.dwg');// The third file
    vCADContainer.AddScaledDXF(vCADFile, 'XREF2', Pos, Scale, 45);
    vCADContainer.GetExtents;
    Image1.Canvas.StretchDraw(Rect(0, 0,
      Round(vCADContainer.Width * Image1.Height / vCADContainer.Height), Image1.Height), vCADContainer);
  finally
    vCADContainer.Free;
  end;
end;

procedure TForm1.LayerInformationClick(Sender: TObject);
var
  vDrawing: TsgCADDXFImage; // Class for DXF format reading
  I: Integer;
  S: string;
begin
  vDrawing := TsgCADDXFImage.Create; //TsgDXFImage - class for DXF file reading
  vDrawing.LoadFromFile('Entities.dxf');
// Gets all blocks from the drawing
  S := 'Layers from file Entities.dxf : ';
  for I := 0 to vDrawing.Converter.Sections[csLayers].Count - 1 do
    S := S + vDrawing.Converter.Sections[csLayers][I].Name + '; ';
  ShowMessage('Layers count: ' + IntToStr(vDrawing.Converter.Sections[csLayers].Count) +
    #13 + S);
  vDrawing.Free;
end;

procedure TForm1.ColorToLineweightClick(Sender: TObject);
var
  vDrawing: TsgCADdxfImage; //The "DXF" unit is required to be added to the clause "uses"
begin
  vDrawing := TsgCADdxfImage.Create;
  try
    vDrawing.LoadFromFile('Entities.dxf'); //Loads an image from a file
    with vDrawing.ColorToLineWeight do
    begin
      Add('clRed=1');//All entities with red color will be drawn with the line width 1
      Add('clYellow=0.75');
      Add('clBlack=2');
    end;
    Image1.Canvas.StretchDraw(Rect(0, 0,
      Round(vDrawing.Width * Image1.Height / vDrawing.Height), Image1.Height), vDrawing);
  finally
    vDrawing.Free;
  end;
end;

end.
