TsgDXFImage.create processor time
Moderators: SDS, support, admin
TsgDXFImage.create processor time
Dear Sergey,
I use the following code, in order to show on my application's main image some instruments that the user has entered into a database. The number of these instruments is in the range of 3000 distinct items. I have run a few time benchmarks on this code, as you can see from the outputdebugstring and I have noticed that it takes about 80 msecs for the TsgDXFImage.Create method to complete!! I know that this is not a long time but if you multiply 3000*80 = 240000/1000 = 240 secs, that is 4 minutes only for the TsgDXFImage create part!! I was wondering if there is another way of achieving the same result, in other words being able to load an external file only once and then just copy it as many times as needed without going through the TsgDXFImage.create part, in order to improve performance?
Kind regards
George
I use the following code, in order to show on my application's main image some instruments that the user has entered into a database. The number of these instruments is in the range of 3000 distinct items. I have run a few time benchmarks on this code, as you can see from the outputdebugstring and I have noticed that it takes about 80 msecs for the TsgDXFImage.Create method to complete!! I know that this is not a long time but if you multiply 3000*80 = 240000/1000 = 240 secs, that is 4 minutes only for the TsgDXFImage create part!! I was wondering if there is another way of achieving the same result, in other words being able to load an external file only once and then just copy it as many times as needed without going through the TsgDXFImage.create part, in order to improve performance?
Kind regards
George
Code: Select all
<b>procedure</b> TfrmMain.AddInstrumentDwg(Instrument : TgnlInstrument; qry : Tquery);
<b>var</b>
v : TsgDXFImage;
t : TsgDXFText;
vIns: TsgDXFInsert;
Tm,Tmf : TDateTime;
TotalTm : Double;
i : Integer;
IDR : TgnlInstrumentDrawingRecord;
<b>begin</b>
tmf := now;
v := TsgDXFImage.Create;
OutputDebugString(PChar(<font color="blue">'After TsgDXFImage.Create '</font id="blue">+FloatToStr(MillisecondsBetween(now,tmf))));
v.IsWithoutBorder := True;
TsgDXFImage(v).LoadFromFile(qry.FieldByName(<font color="blue">'INSTR_DWG_FILE'</font id="blue">).asString);
v.GetExtents;
vIns :=
Img.AddScaledDXFEx
(
v, <i><font color="blue">// TsgDXFImage object for inserting</font id="blue"></i>
INSERT_PREFIX+Instrument.INSTR_UID, <i><font color="blue">// Name</font id="blue"></i>
MakeFPoint(Instrument.INSTR_X-v.Extents.Left-(qry.FieldByName(<font color="blue">'INSTR_DWG_HOTSPOTX'</font id="blue">).asInteger-v.Extents.Left),
Instrument.INSTR_Y-v.Extents.Bottom-(qry.FieldByName(<font color="blue">'INSTR_DWG_HOTSPOTY'</font id="blue">).asInteger-v.Extents.Bottom), 0.0), <i><font color="blue">// position in ACAD coords</font id="blue"></i>
MakeFPoint(1, 1, 1), <i><font color="blue">// scale factor</font id="blue"></i>
0.0 <i><font color="blue">// rotation angle (degrees)</font id="blue"></i>
);
Img.GetExtents;
IDR := TgnlInstrumentDrawingRecord.Create;
IDR.InstumentType := Instrument.INSTR_TYPE;
IDR.DXFInsert := vIns;
fInstrumentList.Add(IDR); <i><font color="blue">// save added Insert entiry in the list</font id="blue"></i>
tm := now;
t := TsgDXFText.Create;
t.Text := Instrument.INSTR_UID;
t.Height := 1;
t.Point := MakeFPoint(Instrument.INSTR_X+(v.Extents.Right-v.Extents.Left), Instrument.INSTR_Y, 0);
t.SetColor(clRed);
t.SetLWeight(1);
t.Scale := 1;
<b>if</b> Assigned(Img.Converter.OnCreate) <b>then</b>
Img.Converter.OnCreate(t);
OutputDebugString(PChar(<font color="blue">'After TsgDXFText '</font id="blue">+FloatToStr(MillisecondsBetween(now,tm))));
Img.Converter.Sections[csEntities].AddEntity(t);
Img.Converter.Loads(t);
fInstrumentTextList.Add(t); <i><font color="blue">// save added Text entiry in the list</font id="blue"></i>
Img.GetExtents;
OutputDebugString(PChar(<font color="blue">'AddInstrumentDwg exit :'</font id="blue">+FloatToStr(MillisecondsBetween(now,tmf))));
<b>end</b>;
Dear George,
<ul><li>The following line is not necessary:</li>
<li>Call when you finish adding all XRefs.</li>
<li>You may duplicate loaded once <b>TsgDXFImage</b> using <b>TsgDXFInsert</b> returned by <b>TsgDXFImage.AddScaledDXFEx</b>. Please see the follwoing example:</li></ul>
Sergey.
please post questions to the forum or write to support@cadsofttools.com
<ul><li>The following line is not necessary:
Code: Select all
v.GetExtents
<li>Call
Code: Select all
TsgDXFImage.GetExtents;
<li>You may duplicate loaded once <b>TsgDXFImage</b> using <b>TsgDXFInsert</b> returned by <b>TsgDXFImage.AddScaledDXFEx</b>. Please see the follwoing example:
Code: Select all
<b>type</b>
TForm1 = <b>class</b>(TForm)
...
sgImage1: TsgImage;
btnAddXRefs: TButton;
<b>procedure</b> btnAddXRefsClick(Sender: TObject);
<b>private</b>
FImg: TsgDXFImage;
...
<b>procedure</b> TForm.btnAddXRefsClick(Sender: TObject);
<b>var</b>
vImg: TsgDXFImage;
vIns, vIns2: TsgDXFInsert;
vPoint: TFPoint;
I: Integer;
<b>begin</b>
sgImage1.LoadFromFile(<font color="blue">'c:\test.dxf'</font id="blue">);
<b>if</b> sgImage1.Picture.Graphic <b>is</b> TsgDXFImage <b>then
begin</b>
FImg := TsgDXFImage(sgImage1.Picture.Graphic);
sgImage1.Align := alClient;
<b>end
else
begin</b>
FImg := <b>nil</b>;
Exit;
<b>end</b>;
vPoint := MakeFPoint(FImg.Extents.Left, FImg.Extents.Bottom, <font color="blue">0</font id="blue">);
vImg := TsgDXFImage.Create;
vImg.LoadFromFile(<font color="blue">'c:\inserted.dxf'</font id="blue">);
vIns := FImg.AddScaledDXFEx(vImg,<font color="blue">'inserted'</font id="blue">,vPoint,MakeFPoint(<font color="blue">0.01</font id="blue">,<font color="blue">0.01</font id="blue">,<font color="blue">0.01</font id="blue">),<font color="blue">0.0</font id="blue">);
<b>for</b> I := <font color="blue">0</font id="blue"> <b>to</b> <font color="blue">300</font id="blue"> <b>do
begin</b>
vIns2 := TsgDXFInsert.Create;
vIns2.AssignEntity(vIns);
vIns2.Point := MakeFPoint(vIns2.Point.X + <font color="blue">50</font id="blue"> * I,vIns2.Point.Y + <font color="blue">50</font id="blue"> * I,vIns2.Point.Z);
FImg.Converter.Sections[csEntities].AddEntity(vIns2);
<b>if</b> Assigned(FImg.Converter.OnCreate) <b>then</b>
FImg.Converter.OnCreate(vIns2);
FImg.Converter.Loads(vIns2);
<b>end</b>;
FImg.GetExtents;
<b>end</b>;
Sergey.
please post questions to the forum or write to support@cadsofttools.com
Dear Sergey,
Thank you for your hint, it has significantly improved the response time of my application, but I still need your help with turning off and deleting the entities after I am through with them. I get AVs when I try to free them and I assume that is because I am saving references to vIns and vIns2 and that causes the DXFimage to be freed more than once. I would greatly appreciate your help on the matter.
Kind regards
George
Thank you for your hint, it has significantly improved the response time of my application, but I still need your help with turning off and deleting the entities after I am through with them. I get AVs when I try to free them and I assume that is because I am saving references to vIns and vIns2 and that causes the DXFimage to be freed more than once. I would greatly appreciate your help on the matter.
Kind regards
George
Dear George,
Here goes the modified code from the previous posting:
Sergey.
please post questions to the forum or write to support@cadsofttools.com
Here goes the modified code from the previous posting:
Code: Select all
<b>procedure</b> TForm1.btnAddXRefsClick(Sender: TObject);
<b>var</b>
vImg: TsgDXFImage;
vIns, vIns2: TsgDXFInsert;
vPoint: TFPoint;
I: Integer;
<b>begin</b>
sgImage1.Visible := False;
sgImage1.LoadFromFile(<font color="blue">'c:\test.dxf'</font id="blue">);
<b>if</b> sgImage1.Picture.Graphic <b>is</b> TsgDXFImage <b>then
begin</b>
FImg := TsgDXFImage(sgImage1.Picture.Graphic);
sgImage1.Align := alClient;
<b>end
else
begin</b>
FImg := <b>nil</b>;
Exit;
<b>end</b>;
vPoint := MakeFPoint(FImg.Extents.Left, FImg.Extents.Bottom, <font color="blue">0</font id="blue">);
vImg := TsgDXFImage.Create;
vImg.LoadFromFile(<font color="blue">'c:\inserted.dxf'</font id="blue">);
vIns := FImg.AddScaledDXFEx(vImg,<font color="blue">'Inserted'</font id="blue">,vPoint,MakeFPoint(<font color="blue">0.01</font id="blue">, <font color="blue">0.01</font id="blue">, <font color="blue">0.01</font id="blue">), <font color="blue">0.0</font id="blue">);
<b>if</b> FXRefsList = <b>nil then</b>
FXRefsList := TList.Create;
<b>or</b> I := <font color="blue">0</font id="blue"> <b>to</b> <font color="blue">30</font id="blue"> <b>do
begin</b>
vIns2 := TsgDXFInsert.Create;
vIns2.AssignEntity(vIns);
vIns2.Point := MakeFPoint(vIns2.Point.X + <font color="blue">50</font id="blue"> * I,vIns2.Point.Y + <font color="blue">50</font id="blue"> * I,vIns2.Point.Z);
FXRefsList.Add(vIns2);
FImg.Converter.Sections[csEntities].AddEntity(vIns2);
<b>if</b> Assigned(FImg.Converter.OnCreate) <b>then</b>
FImg.Converter.OnCreate(vIns2);
FImg.Converter.Loads(vIns2);
<b>end</b>;
FImg.GetExtents;
sgImage1.Visible := True;
<b>end</b>;
<b>procedure</b> TForm1.btnDeleteXRefsClick(Sender: TObject);
<b>var</b>
vInsert: TsgDXFInsert;
I, J: Integer;
<b>begin</b>
sgImage1.Visible := False;
<b>if</b> (FXRefsList = <b>nil</b>) <b>and</b> (FImg = <b>nil</b>) <b>then</b>
Exit;
<b>for</b> I := FImg.Converter.Counts[csEntities] - <font color="blue">1</font id="blue"> <b>downto</b> <font color="blue">0</font id="blue"> <b>do
begin
if</b> FImg.Converter.Sections[csEntities].Entities[I] <b>is</b> TsgDXFInsert <b>then
begin</b>
vInsert := TsgDXFInsert(FImg.Converter.Sections[csEntities].Entities[I]);
J := FXRefsList.IndexOf(vInsert);
<b>if</b> J > -<font color="blue">1</font id="blue"> <b>then
begin</b>
vInsert.Block := <b>nil</b>;
FImg.Converter.DeleteEntity(vInsert, True);
FXRefsList.Delete(J);
<b>end</b>;
<b>end</b>;
<b>end</b>;
FXRefsList.Free;
FImg.GetExtents;
sgImage1.Visible := True;
<b>end</b>;
please post questions to the forum or write to support@cadsofttools.com