how to create empty TsgDXFImage

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

Moderators: SDS, support, admin

Post Reply
slbarker
Posts: 12
Joined: 03 Nov 2005, 23:39
Location: New Zealand

how to create empty TsgDXFImage

Post by slbarker » 25 Oct 2006, 13:10

Hi Sergey,

I would like to create a new blank TsgDXFImage - what is the minimum code to do this? (I don't want to loadfromfile). It can contain a rectangle of a certain size if it needs to have at least 1 entity.

Also, in my sgImagePaint - I am overlaying a bmp, but I need the blank dxf to be sized to fit the size of the bitmap. If the dxf contains a single rectangle the same shape as the bitmap then I can keep this as a border - although this is not the main objective.

FYI the application currently loads dxf and dwg files as per your viewer demo, but lets the user measure items on the drawing and sends the data to a separate quantity surveying application. Measurements are saved in a separate file from the original drawing. Now I need to let users open bitmaps etc but still perform the same measurements (hence the need for a blank dxf present as all my measurement code is attached to the TsgImage class). I have a calibration step so users can get the scale of the bitmap correct.

Thanks,
Steve

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

Post by support » 25 Oct 2006, 17:52

Hello Steve,

Please examine the following example (we add a line entity to ensure the extents stay correct):

Code: Select all

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

<b>type</b>
  TForm1 = <b>class</b>(TForm)
    Button1: TButton;
    Image1: TImage;
    <b>procedure</b> Button1Click(Sender: TObject);
  <b>private</b>
    <i><font color="blue">{ Private declarations }</font id="blue"></i>
    FImg: TsgDXFImage;
...

<b>procedure</b> TForm1.Button1Click(Sender: TObject);
<b>var</b>
  vFRect: TFRect;
  vLine: TsgDXFLine;
  vBitMap: TBitmap; 
<b>begin</b>
  vFRect := MakeFRect(<font color="blue">0</font id="blue">,<font color="blue">100</font id="blue">,<font color="blue">0</font id="blue">, <font color="blue">100</font id="blue">,<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">);
  FImg := TsgDXFImage.Create;
  FImg.IsWithoutBorder := True;
  vLine := TsgDXFLine.Create;
  vLine.Point := MakeFPoint(<font color="blue">20</font id="blue">,<font color="blue">20</font id="blue">,<font color="blue">0</font id="blue">);
  vLine.Point1 := MakeFPoint(<font color="blue">80</font id="blue">,<font color="blue">80</font id="blue">,<font color="blue">0</font id="blue">);
  FImg.Converter.Sections[csEntities].AddEntity(vLine);
  <b>if</b> Assigned(FImg.Converter.OnCreate) <b>then</b>
    FImg.Converter.OnCreate(vLine);
  FImg.Converter.Loads(vLine);
  FImg.CurrentLayout := FImg.Layouts[<font color="blue">0</font id="blue">];
  FImg.DrawingBox := vFRect;
  vBitMap := TBitmap.Create;
  vBitMap.Width := 100;
  vBitMap.Height := 100;
  FImg.DrawRect(vBitMap.Canvas.Handle, FImg.Extents, vBitMap.Canvas.ClipRect);
  vBitMap.SaveToFile(<font color="blue">'c:\BlankDXF.bmp'</font id="blue">);
  Image1.Picture.LoadFromFile(<font color="blue">'c:\BlankDXF.bmp'</font id="blue">);
  vBitMap.Free;
<b>end</b>;
Sergey.

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

slbarker
Posts: 12
Joined: 03 Nov 2005, 23:39
Location: New Zealand

Post by slbarker » 26 Oct 2006, 08:11

Thanks Sergey.

I've incorporated some of your code, but still can't see how to assign the newly created TsgDXFImage to the sgPaintBox (class TsgImage).

Here's the code for opening the file. It is the case where the file is a bitmap that I am trying to resolve. It fails on the line:

Code: Select all

sgPaintBox.Picture.Graphic.Assign(Img);
I want to end up with the new Img object copied into the above, just as if it was loaded from file.

thanks,
Steve

Code: Select all

procedure TfrmMain.Open(const sFileName: string);
var
  ext : string;
  vLine: TsgDXFLine;
begin
  FFileName := sFileName;
  Start := GetCurrentTime;
  Screen.Cursor := crHourGlass;
  sgPaintBox.IsBigScale := False;
  try
    ext := LowerCase(ExtractFileExt(sFileName));
    if ext = '.bmp' then begin
      BMOverlay.LoadFromFile(sFileName);  // bitmap overlay

      //sgPaintBox.LoadFromFile(ExtractFilePath(Application.ExeName)+'frame.dxf');  // dummy frame
      //sgPaintBox.Height := BMOverlay.Height;
      //sgPaintBox.Width := BMOverlay.Width;
      //Img := TsgDXFImage(sgPaintBox.Picture.Graphic);

      // create a dummy blank dxf image so we have something to draw on
      Img := TsgDXFImage.Create;
      try
        Img.IsWithoutBorder := True;
        vLine := TsgDXFLine.Create;
        try
          vLine.Point := MakeFPoint(0,0,0);
          vLine.Point1 := MakeFPoint(0,BMOverlay.Height,0);
          Img.Converter.Sections[csEntities].AddEntity(vLine);
    {
          vLine.Point := MakeFPoint(0,BMOverlay.Height,0);
          vLine.Point1 := MakeFPoint(BMOverlay.Width,BMOverlay.Height,0);
          Img.Converter.Sections[csEntities].AddEntity(vLine);
          vLine.Point := MakeFPoint(BMOverlay.Width,BMOverlay.Height,0);
          vLine.Point1 := MakeFPoint(BMOverlay.Width,0,0);
          Img.Converter.Sections[csEntities].AddEntity(vLine);
          vLine.Point := MakeFPoint(BMOverlay.Width,0,0);
          vLine.Point1 := MakeFPoint(0,0,0);
          Img.Converter.Sections[csEntities].AddEntity(vLine);
    }
          if Assigned(Img.Converter.OnCreate) then
            Img.Converter.OnCreate(vLine);
          Img.Converter.Loads(vLine);
        finally
          vLine.free;
        end;  
        Img.CurrentLayout := Img.Layouts[0];
        Img.DrawingBox := MakeFRect(0,BMOverlay.Height,0, BMOverlay.Width,0,0);
<font color="red">        sgPaintBox.Picture.Graphic.Assign(Img);</font id="red">
        sgPaintBox.Invalidate;
        IsBitMap := true;
      finally
        Img.Free;
      end;
      Img := TsgDXFImage(sgPaintBox.Picture.Graphic);

    end else begin
      sgPaintBox.LoadFromFile(sFileName);
      Img := TsgDXFImage(sgPaintBox.Picture.Graphic);
      IsBitMap := false;
    end;
    if sgPaintBox.Picture.Graphic is TBitmap then
      sgPaintBox.Picture.Bitmap.HandleType := bmDDB;
    MIClose.Enabled := True;
    btnLayers.Enabled := True;
    pnlFileName.Caption := UpperCase(ExtractFileName(sFileName));
    EnableScales;
    HelpContext := 3;
    MIAutoClick(nil);
    //if not (sgPaintBox.Picture.Graphic is TsgDXFImage) then begin //Exit;
    sgPaintBox.IsBigScale := True; // turn on accurate CAD scaling
    SetImgOpt;
    MIPrint.Enabled := True;
    MiOEM.Enabled := True;
    MiOEM.Checked := not Img.Converter.OEM;
    MiOEMClick(nil);
    sgPaintBox.ScaleMMWidth := Img.AbsWidth;
    // create toolbar if neccessary
    if not Assigned(frmNewToolBar) then begin
      frmNewToolBar := TfrmNewToolBar.Create(Application);
      // keep reference to the Image we are using
      frmNewToolBar.Image := frmMain.sgPaintBox;
      frmNewToolBar.LoadToolBars(FOptions);
      frmNewToolBar.PMJobNo := PMJobNo;
    end;
    frmNewToolBar.Factor := FFactor;
    frmNewToolBar.Show;
    EntList.LoadMeasurements(ChangeFileExt(FFileName, '.txt'));
  finally
    ProgressBar1.Position := 0;
    Screen.Cursor := crDefault;
    miSaveAs.Enabled := sgPaintBox.Picture.Graphic is TsgDXFImage;
    SetBtnEnable(sgPaintBox.Picture.Graphic is TsgDXFImage);
  end;
end;

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

Post by support » 30 Oct 2006, 17:26

Hello Steve,

Please try the following way:

Code: Select all

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

<b>type</b>
  TForm1 = <b>class</b>(TForm)
    ...
    <b>procedure</b> Button1Click(Sender: TObject);
  <b>private</b>
    <i><font color="blue">{ Private declarations }</font id="blue"></i>
    FImg: TsgDXFImage;
...

<b>procedure</b> TForm1.Button1Click(Sender: TObject);
<b>var</b>
  vLine: TsgDXFLine;
  vBitMap: TBitmap;
<b>begin</b>
  sgPaintBox.IsBigScale := False;
  vBitMap := TBitmap.Create;
  vBitMap.LoadFromFile(<font color="blue">'c:\Line.bmp'</font id="blue">);  <i><font color="blue">// bitmap overlay
      // create a dummy blank dxf image so we have something to draw on</i></font id="blue">
  FImg := TsgDXFImage.Create;
  <b>try</b>
    FImg.IsWithoutBorder := True;
    vLine := TsgDXFLine.Create;
    FImg.Converter.Sections[csEntities].AddEntity(vLine);
    vLine.Point := MakeFPoint(<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">);
    vLine.Point1 := MakeFPoint(vBitMap.Width,vBitMap.Height,0);
    FImg.Converter.Loads(vLine);
    FImg.CurrentLayout := FImg.Layouts[<font color="blue">0</font id="blue">];
  <b>finally</b>
    sgPaintBox.Picture.Graphic := FImg;
    FImg.Free;
    FImg := TsgDXFImage(sgPaintBox.Picture.Graphic);
    FImg.DrawingBox := MakeFRect(<font color="blue">0</font id="blue">,vBitMap.Height,<font color="blue">0</font id="blue">, vBitMap.Width,<font color="blue">0</font id="blue">,<font color="blue">0</font id="blue">);
    vBitMap.Free;
  <b>end</b>;
  sgPaintBox.Invalidate;
<b>end</b>;
Sergey

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

slbarker
Posts: 12
Joined: 03 Nov 2005, 23:39
Location: New Zealand

Post by slbarker » 01 Nov 2006, 01:55

Thanks Sergey,

That has helped but I found I also needed to:

Img.GetExtents;

Now it all works (including the calibration) the same as when I was exporting and importing from a temporary dxf file.

I've also reduced the dummy rectangle down to 4 small corner markers so they are less obtrusive. Later, I'm going to try to draw these white on white so they are invisible.

Much appreciated,

Steve

Post Reply