Discuss and ask questions about CAD VCL (Delphi and C++ Builder).
Moderators: SDS, support, admin
-
gnl
- Posts: 9
- Joined: 05 Oct 2006, 23:40
- Location: Greece
Post
by gnl » 19 Oct 2006, 23:30
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
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>;
-
support
- Posts: 3272
- Joined: 30 Mar 2005, 11:36
-
Contact:
Post
by support » 20 Oct 2006, 14:31
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:
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>;
</li></ul>
Sergey.
please post questions to the forum or write to
support@cadsofttools.com
-
gnl
- Posts: 9
- Joined: 05 Oct 2006, 23:40
- Location: Greece
Post
by gnl » 24 Oct 2006, 00:03
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
-
support
- Posts: 3272
- Joined: 30 Mar 2005, 11:36
-
Contact:
Post
by support » 24 Oct 2006, 12:12
Dear George,
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>;
Sergey.
please post questions to the forum or write to
support@cadsofttools.com