VBA
Discuss AutoCAD ActiveX and VBA (Visual Basic for Applications) questions here.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Which transform (copy) method is faster?

19 REPLIES 19
Reply
Message 1 of 20
Anonymous
331 Views, 19 Replies

Which transform (copy) method is faster?

I have written a VB app that needs to retrieve specific entities (sometimes over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities transforming them one by one OR...

put them in a selection set and then execute the Copy command via sendcommand.

I would have tried this myself but I don't understand how to use the selection set I added the entities to as part of the SENDCOMMAND verbage or if there is a way to 'select' them via code before using the Sendcommand "Copy"

Any and all input on this issue will be greatly appreciated... I don't know how many more times I can bang my head against the wall without it or the wall being damaged. 🙂
19 REPLIES 19
Message 2 of 20
Anonymous
in reply to: Anonymous

Hi,

This may give some ideas. It follows the general principle of wherever
possible avoiding sendcommand entirely.


Sub ssTest()
Dim oObj As AcadObject
Dim lTmp As Long
Dim ssObjects As AcadSelectionSet
Dim oLine As AcadLine
Dim oMText As AcadMText
Dim Distance As Double, Direction As Double
Distance = 10
Direction = 0
If SelectObjectsOnLayer(ssObjects, "LINE,MTEXT", "*") > 0 Then
For Each oObj In ssObjects
If TypeOf oObj Is AcadLine Then
Set oLine = oObj
Set oLine = oLine.Copy
MoveLine oLine, Distance, Direction
ElseIf TypeOf oObj Is AcadMText Then
Set oMText = oObj
Set oMText = oMText.Copy
'Function to move new Mtext as required
End If
Next
End If

End Sub ' ssTest()


Function MoveLine(oLine As AcadLine, Distance As Double, Direction As
Double)

oLine.StartPoint = ThisDrawing.Utility.PolarPoint(oLine.StartPoint,
Direction, Distance)
oLine.EndPoint = ThisDrawing.Utility.PolarPoint(oLine.EndPoint, Direction,
Distance)

End Function

''''''''''''''''''''''''''''' '''''''''''''''''''
Public Function SelectObjectsOnLayer(ssObs As AcadSelectionSet, spObjectType
As String, spLayer As String) As Long
On Error GoTo SOLErrorHandler
Dim FilterType(0 To 1) As Integer
Dim FilterData(0 To 1) As Variant
Dim sNumber As String
FilterType(0) = 0: FilterData(0) = spObjectType
FilterType(1) = 8: FilterData(1) = spLayer
' The line below will create an error if the SSET doesn't exist
' or delete it if it does exist.
' The ON Error will allow the program to continue and create the set
On Error Resume Next
ThisDrawing.SelectionSets.Item("SSET").Delete
If Err Then Err.Clear
On Error GoTo SOLErrorHandler
Set ssObs = ThisDrawing.SelectionSets.Add("SSET")
ssObs.Select acSelectionSetAll, , , FilterType, FilterData
SelectObjectsOnLayer = ssObs.Count
Exit Function

SOLErrorHandler:
Err.Clear
SelectObjectsOnLayer = 0
End Function ' SelectObjectsOnLayer()


wrote in message news:5671345@discussion.autodesk.com...
I have written a VB app that needs to retrieve specific entities (sometimes
over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities
transforming them one by one OR...

put them in a selection set and then execute the Copy command via
sendcommand.

I would have tried this myself but I don't understand how to use the
selection set I added the entities to as part of the SENDCOMMAND verbage or
if there is a way to 'select' them via code before using the Sendcommand
"Copy"

Any and all input on this issue will be greatly appreciated... I don't know
how many more times I can bang my head against the wall without it or the
wall being damaged. 🙂
Message 3 of 20
Anonymous
in reply to: Anonymous

Thanks Laurie... I will heed your word of advice.

On another subject seeing I have your attention... I have written a rather large vb exe that runs independently of ACAD while ACAD is open. It adds, removes, and modifies ACAD entities to the open ACAD dwg. From what I am reading on other post... converting the VB app to a activex dll will drastically improve the speed it takes to add and modifies entities in the ACAD session. If so, is there a good post that could help me make this conversion? And leaning on your experience... are there pitfalls that I should be aware of.. you know, things or methods to avoid?

Thanks again
Message 4 of 20
Anonymous
in reply to: Anonymous

Me again... I noticed in your MoveLine function that you do not use the .update. Is it neccessary and if not, does it add additional time to the process?
Message 5 of 20
Anonymous
in reply to: Anonymous

If you do your work from stand-alone exe app (automating AutoCAD), then it
does not make difference where you move your Acad related operation into a
dll or not, because the dll code is still running in the process of your
app, not Acad, you still have to communicate between two processes - Acad
and your app, that is where the slowness occurs.


wrote in message news:5671648@discussion.autodesk.com...
Thanks Laurie... I will heed your word of advice.

On another subject seeing I have your attention... I have written a rather
large vb exe that runs independently of ACAD while ACAD is open. It adds,
removes, and modifies ACAD entities to the open ACAD dwg. From what I am
reading on other post... converting the VB app to a activex dll will
drastically improve the speed it takes to add and modifies entities in the
ACAD session. If so, is there a good post that could help me make this
conversion? And leaning on your experience... are there pitfalls that I
should be aware of.. you know, things or methods to avoid?

Thanks again
Message 6 of 20
Anonymous
in reply to: Anonymous

Thanks for your help Norman!

So you are saying... if I convert my app to a dll that will be started in ACAD that there will not be a performance improvement. I was under the impression that if you make a call to a dll from within the ACAD vba environment that is runs in ACAD's process and therefore is much faster.

A little background on my app... it must be started while ACAD is running... preferably from ACAD though right now it can be started like any other exe. The app runs until the user exits ACAD. If I create an activex dll... it would work the same way... running, once started, until ACAD closes.
Message 7 of 20
Anonymous
in reply to: Anonymous

Hi,

When creating this bit of code Update didn't occur to me as necessary to
illustrate the copy method.

In the same way, there is no error checking (except as needed in the
SelectObjectsOnLayer)

As far as I'm aware Update works on the graphic screen display of the
object. The object itself is added to the database by the API without it.

If you are drawing a small number of objects and are interested in seeing
them - perhaps while you are debugging the code then use Update. However
long it takes would be trivial.

If you are drawing a large and potentially unknown number of objects, you
may not wish to update the screen during the process to save time. It would
certainly seem to be a waste of time to start an update on an object which
was drawn outside the current view.

You can run a regen at the end of a function if it suits, or any of the zoom
commands which update the screen

If timing is critical then the best way to check it is to write some code to
create large numbers of something and wrap it in a timer so that you can
work with real numbers on the time effects of different code.

Most of the code I write does very little drafting, so I could safely use
Update without human observable effects.

About the VB query:

If speed is a real issue, why not port the AutoCAD interaction side of the
code to VBA?

The non-AutoCAD bits can easily be poked into a DLL called from the VBA
environment and the EXE file abandoned.

--

Laurie Comerford
CADApps
www.cadapps.com.au
www.civil3Dtools.com

wrote in message news:5671650@discussion.autodesk.com...
Me again... I noticed in your MoveLine function that you do not use the
.update. Is it neccessary and if not, does it add additional time to the
process?
Message 8 of 20
Anonymous
in reply to: Anonymous

Laurie - Consider learning to use the API properly,
before you attempt to show/teach others how to use it.

I'm not going to say any more than that, other than
what you just posted is horrendus and not even worth
of being classified as 'entry level'.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

"Laurie Comerford" wrote in message news:5671420@discussion.autodesk.com...
Hi,

This may give some ideas. It follows the general principle of wherever
possible avoiding sendcommand entirely.


Sub ssTest()
Dim oObj As AcadObject
Dim lTmp As Long
Dim ssObjects As AcadSelectionSet
Dim oLine As AcadLine
Dim oMText As AcadMText
Dim Distance As Double, Direction As Double
Distance = 10
Direction = 0
If SelectObjectsOnLayer(ssObjects, "LINE,MTEXT", "*") > 0 Then
For Each oObj In ssObjects
If TypeOf oObj Is AcadLine Then
Set oLine = oObj
Set oLine = oLine.Copy
MoveLine oLine, Distance, Direction
ElseIf TypeOf oObj Is AcadMText Then
Set oMText = oObj
Set oMText = oMText.Copy
'Function to move new Mtext as required
End If
Next
End If

End Sub ' ssTest()


Function MoveLine(oLine As AcadLine, Distance As Double, Direction As
Double)

oLine.StartPoint = ThisDrawing.Utility.PolarPoint(oLine.StartPoint,
Direction, Distance)
oLine.EndPoint = ThisDrawing.Utility.PolarPoint(oLine.EndPoint, Direction,
Distance)

End Function

''''''''''''''''''''''''''''' '''''''''''''''''''
Public Function SelectObjectsOnLayer(ssObs As AcadSelectionSet, spObjectType
As String, spLayer As String) As Long
On Error GoTo SOLErrorHandler
Dim FilterType(0 To 1) As Integer
Dim FilterData(0 To 1) As Variant
Dim sNumber As String
FilterType(0) = 0: FilterData(0) = spObjectType
FilterType(1) = 8: FilterData(1) = spLayer
' The line below will create an error if the SSET doesn't exist
' or delete it if it does exist.
' The ON Error will allow the program to continue and create the set
On Error Resume Next
ThisDrawing.SelectionSets.Item("SSET").Delete
If Err Then Err.Clear
On Error GoTo SOLErrorHandler
Set ssObs = ThisDrawing.SelectionSets.Add("SSET")
ssObs.Select acSelectionSetAll, , , FilterType, FilterData
SelectObjectsOnLayer = ssObs.Count
Exit Function

SOLErrorHandler:
Err.Clear
SelectObjectsOnLayer = 0
End Function ' SelectObjectsOnLayer()


wrote in message news:5671345@discussion.autodesk.com...
I have written a VB app that needs to retrieve specific entities (sometimes
over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities
transforming them one by one OR...

put them in a selection set and then execute the Copy command via
sendcommand.

I would have tried this myself but I don't understand how to use the
selection set I added the entities to as part of the SENDCOMMAND verbage or
if there is a way to 'select' them via code before using the Sendcommand
"Copy"

Any and all input on this issue will be greatly appreciated... I don't know
how many more times I can bang my head against the wall without it or the
wall being damaged. 🙂
Message 9 of 20
Anonymous
in reply to: Anonymous

The code Laurie posted is a good example of
bad programming and how not to write code.

First, he doesn't seem to know about the Move()
method of AcadEntity, so he writes his own that
is entity-specific and hence, requires a different
implementation for each entity type.

Second, if your code is not running in AutoCAD
as a DLL (or as VBA code), then the issue of
what method of moving objects is faster, is a
moot point.

If your DLL is running in AutoCAD, the way to do
it if you don't want to use SendCommand, is to
simply loop through your selection set, and call
each entity's Move() method.

There no need to write dedicated functions to
move each type of entity, like the "MoveLine"
function laurie posted. That's because every
entity in an AutoCAD drawing already knows how
to move itself, and all you need to do is tell it
to, by calling the Move() method.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5671650@discussion.autodesk.com...
Me again... I noticed in your MoveLine function that you do not use the .update. Is it neccessary and if not, does it add additional time to the process?
Message 10 of 20
Anonymous
in reply to: Anonymous

What I was saying, if the dll is loaded into your exe app, then it would not
help in the regard of speed. If it is called in Acad VBA, the it should be
the same as VBA code. Since I have no idea how your app and Acad work
together and what they do, I cannot tell more.


"gmyroup" wrote in message news:5672282@discussion.autodesk.com...
Thanks for your help Norman!

So you are saying... if I convert my app to a dll that will be started in
ACAD that there will not be a performance improvement. I was under the
impression that if you make a call to a dll from within the ACAD vba
environment that is runs in ACAD's process and therefore is much faster.

A little background on my app... it must be started while ACAD is running...
preferably from ACAD though right now it can be started like any other exe.
The app runs until the user exits ACAD. If I create an activex dll... it
would work the same way... running, once started, until ACAD closes.
Message 11 of 20
Anonymous
in reply to: Anonymous

Hi Tony,

Hallelujah. Hallelujah. Hallelujah
HHHaaaaallllllllleeeeellllllllluuuuuujjjjjjjaaaahhhhhhhh

What happened? You slipped up in your torrent of abuse and took the risk of
providing a testable hint as to how my code could be improved.

Yes, I was unaware of the AcadEntity.Move functionality.

Thank you, thank you, thank you.

I changed the original code a little to use AcadEntity.Move in the loop
rather than an AcadObject which doesn't have a move method and hence, as you
implied, for that code my MoveLine function and other entity specific code
is no longer needed.

I also amended the original post with the line of code as below to move the
Mtext

oMtext.InsertionPoint =
ThisDrawing.Utility.PolarPoint(oMtext.InsertionPoint, Direction, Distance)

Here is the results of some timing tests I did for a drawing with one line
and one item of Mtext. I ran each set of code three times.

1000 Lines and Mtext Items with entity.move 2.96875 seconds
1000 Lines and Mtext Items with entity.move 2.859375 seconds
1000 Lines and Mtext Items with entity.move 2.984375 seconds

1000 Lines and Mtext Items with Original code 1.609375 seconds
1000 Lines and Mtext Items with Original code 1.65625 seconds
1000 Lines and Mtext Items with Original code 1.609375 seconds

So now we have
"The code Laurie posted is a good example of bad programming and how not to
write code."

It seems strange then that it:

A Performs the required task
B Only takes about 55% of the time of the Entity.Move command process
takes to complete the test data.

As always, I ask you to back up your insults with real data to try and
justify them. And, as always, I know you'll wimp out on some pathetic
grounds.

Sub sTest()
Dim oEnt As AcadEntity
Dim PtStart(0 To 2) As Double
Dim vPt As Variant
Dim ssObjects As AcadSelectionSet
Dim Distance As Double, Direction As Double
Distance = 10
Direction = 0
vPt = ThisDrawing.Utility.PolarPoint(PtStart, Direction, Distance)
If SelectObjectsOnLayer(ssObjects, "LINE,MTEXT", "*") > 0 Then
For Each oEnt In ssObjects
Set oEnt = oEnt.Copy
oEnt.Move PtStart, vPt
Next
End If

End Sub ' ssTest()


--

Laurie Comerford
CADApps
www.cadapps.com.au
www.civil3Dtools.com
"Tony Tanzillo" wrote in message
news:5672307@discussion.autodesk.com...
The code Laurie posted is a good example of
bad programming and how not to write code.

First, he doesn't seem to know about the Move()
method of AcadEntity, so he writes his own that
is entity-specific and hence, requires a different
implementation for each entity type.

Second, if your code is not running in AutoCAD
as a DLL (or as VBA code), then the issue of
what method of moving objects is faster, is a
moot point.

If your DLL is running in AutoCAD, the way to do
it if you don't want to use SendCommand, is to
simply loop through your selection set, and call
each entity's Move() method.

There no need to write dedicated functions to
move each type of entity, like the "MoveLine"
function laurie posted. That's because every
entity in an AutoCAD drawing already knows how
to move itself, and all you need to do is tell it
to, by calling the Move() method.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5671650@discussion.autodesk.com...
Me again... I noticed in your MoveLine function that you do not use the
.update. Is it neccessary and if not, does it add additional time to the
process?
Message 12 of 20
Anonymous
in reply to: Anonymous

try TransformBy method. Copied 2000 entities in 0.421875 seconds...

wrote in message news:5671345@discussion.autodesk.com...
I have written a VB app that needs to retrieve specific entities (sometimes
over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities
transforming them one by one OR...

put them in a selection set and then execute the Copy command via
sendcommand.

I would have tried this myself but I don't understand how to use the
selection set I added the entities to as part of the SENDCOMMAND verbage or
if there is a way to 'select' them via code before using the Sendcommand
"Copy"

Any and all input on this issue will be greatly appreciated... I don't know
how many more times I can bang my head against the wall without it or the
wall being damaged. 🙂
Message 13 of 20
Anonymous
in reply to: Anonymous

>try TransformBy method

actually TransformBy is a property... entity.TransformBy

"Paul Richardson" wrote in message
news:5672465@discussion.autodesk.com...
try TransformBy method. Copied 2000 entities in 0.421875 seconds...

wrote in message news:5671345@discussion.autodesk.com...
I have written a VB app that needs to retrieve specific entities (sometimes
over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities
transforming them one by one OR...

put them in a selection set and then execute the Copy command via
sendcommand.

I would have tried this myself but I don't understand how to use the
selection set I added the entities to as part of the SENDCOMMAND verbage or
if there is a way to 'select' them via code before using the Sendcommand
"Copy"

Any and all input on this issue will be greatly appreciated... I don't know
how many more times I can bang my head against the wall without it or the
wall being damaged. 🙂
Message 14 of 20
Anonymous
in reply to: Anonymous

>actually TransformBy is a property... entity.TransformBy

not it's NOT... I was right the first time. WOW! Anyway it's FAST.

"Paul Richardson" wrote in message
news:5672501@discussion.autodesk.com...
>try TransformBy method

actually TransformBy is a property... entity.TransformBy

"Paul Richardson" wrote in message
news:5672465@discussion.autodesk.com...
try TransformBy method. Copied 2000 entities in 0.421875 seconds...

wrote in message news:5671345@discussion.autodesk.com...
I have written a VB app that needs to retrieve specific entities (sometimes
over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities
transforming them one by one OR...

put them in a selection set and then execute the Copy command via
sendcommand.

I would have tried this myself but I don't understand how to use the
selection set I added the entities to as part of the SENDCOMMAND verbage or
if there is a way to 'select' them via code before using the Sendcommand
"Copy"

Any and all input on this issue will be greatly appreciated... I don't know
how many more times I can bang my head against the wall without it or the
wall being damaged. 🙂
Message 15 of 20
Anonymous
in reply to: Anonymous

Hi Paul,

Grabbing some sample code from the help system I ended up with:

Sub TestTransformBy()
Dim oEnt As AcadEntity
Dim oEntDup As AcadEntity
Dim PtStart(0 To 2) As Double
Dim i As Integer
Dim vPt As Variant
Dim lTmp As Long
Dim ssObjects As AcadSelectionSet
Dim TimeStart, TimeEnd
Dim transMat(0 To 3, 0 To 3) As Double
transMat(0, 0) = 1#: transMat(0, 1) = 0#: transMat(0, 2) = 0#:
transMat(0, 3) = 10#
transMat(1, 0) = 0#: transMat(1, 1) = 1#: transMat(1, 2) = 0#:
transMat(1, 3) = 0#
transMat(2, 0) = 0#: transMat(2, 1) = 0#: transMat(2, 2) = 1#:
transMat(2, 3) = 0#
transMat(3, 0) = 0#: transMat(3, 1) = 0#: transMat(3, 2) = 0#:
transMat(3, 3) = 1#
If SelectObjectsOnLayer(ssObjects, "LINE,MTEXT", "*") > 0 Then
TimeStart = 60 * Val(Format(Time, "MM")) + Val(Format(Time, "SS.SSS"))
For Each oEnt In ssObjects
For i = 1 To 1000
Set oEntDup = oEnt.Copy
oEntDup.TransformBy (transMat)
Next i
Next
TimeEnd = 60 * Val(Format(Time, "MM")) + Val(Format(Time, "SS.SSS"))
Debug.Print "1000 Lines and Mtext Items with TransformBy ",
Format(TimeEnd - TimeStart, "#0.0"); "seconds"
End If
End Sub ' ssTest()


For three runs in a drawing containing one line and one MText item this
reported. After each run I simply used the Undo command to remove the new
data.

1000 Lines and Mtext Items with TransformBy 4.0seconds
1000 Lines and Mtext Items with TransformBy 4.0seconds
1000 Lines and Mtext Items with TransformBy 4.0seconds


As it seemed significantly slower for the same data set on my computer I ran
the other methods again with the following results.

1000 Lines and Mtext Items with move 4.0seconds
1000 Lines and Mtext Items with move 4.0seconds
1000 Lines and Mtext Items with move 4.0seconds

1000 Lines and Mtext Items with Original code 2.0seconds
1000 Lines and Mtext Items with Original code 2.0seconds
1000 Lines and Mtext Items with Original code 2.0seconds

The only difference between when the first code was run and new is time
elapsed with AutoCAD open and that there is another 3Mb drawing open

Original Reports
1000 Lines and Mtext Items with entity.move 2.96875 seconds
1000 Lines and Mtext Items with entity.move 2.859375 seconds
1000 Lines and Mtext Items with entity.move 2.984375 seconds

1000 Lines and Mtext Items with Original code 1.609375 seconds
1000 Lines and Mtext Items with Original code 1.65625 seconds
1000 Lines and Mtext Items with Original code 1.609375 seconds

I'd be interested to see the results from your computer as there is nearly a
ten times difference in the output.
Also, my time measurement is more suited to comparisons on one computer than
anything else.

I'm running this in Civil 3D R2008. Although for comparisons with my other
times, that should be irrelevant.

I've never had cause to write code to move objects previously other than for
changing the insertion point of my test doughnut to highlight the point I've
just computed when I'm doing complex geometry and de-bugging. In that type
of code, setting the insertion to a computed point is the obvious answer.


--

Laurie Comerford
CADApps
www.cadapps.com.au
www.civil3Dtools.com

Sub TestTransformBy()
Dim oEnt As AcadEntity

Dim PtStart(0 To 2) As Double
Dim i As Integer
Dim vPt As Variant
Dim lTmp As Long
Dim ssObjects As AcadSelectionSet
Dim TimeStart, TimeEnd
Dim transMat(0 To 3, 0 To 3) As Double
transMat(0, 0) = 1#: transMat(0, 1) = 0#: transMat(0, 2) = 0#:
transMat(0, 3) = 10#
transMat(1, 0) = 0#: transMat(1, 1) = 1#: transMat(1, 2) = 0#:
transMat(1, 3) = 0#
transMat(2, 0) = 0#: transMat(2, 1) = 0#: transMat(2, 2) = 1#:
transMat(2, 3) = 0#
transMat(3, 0) = 0#: transMat(3, 1) = 0#: transMat(3, 2) = 0#:
transMat(3, 3) = 1#
If SelectObjectsOnLayer(ssObjects, "LINE,MTEXT", "*") > 0 Then
TimeStart = Timer
For Each oEnt In ssObjects
For i = 1 To 1000
Set oEnt = oEnt.Copy
oEnt.TransformBy (transMat)
Next i
Next
TimeEnd = Timer
Debug.Print "1000 Lines and Mtext Items with TransformBy ",
TimeEnd - TimeStart; "seconds"
End If
End Sub ' ssTest()
"Paul Richardson" wrote in message
news:5672502@discussion.autodesk.com...
>actually TransformBy is a property... entity.TransformBy

not it's NOT... I was right the first time. WOW! Anyway it's FAST.

Message 16 of 20
Anonymous
in reply to: Anonymous

This is using ADT06. All things being equal is may not be faster
but still worth a try for him... This is on a relatively slow laptop
too.

1000 1 unit lines
1000 mtext = "foo"

MS Count 2000
-0.3901367
MS Count 4000

MS Count 2000
-0.4060059
MS Count 4000

MS Count 2000
-0.4069824
MS Count 4000

[code]
Sub foo()

Dim startTime, endTime

Dim tm(3, 3) As Double
tm(0, 0) = 1: tm(0, 1) = 0
tm(0, 2) = 0: tm(0, 3) = 1
tm(1, 0) = 0: tm(1, 1) = 1
tm(1, 2) = 0: tm(1, 3) = 1
tm(2, 0) = 0: tm(2, 1) = 0
tm(2, 2) = 1: tm(2, 3) = 0
tm(3, 0) = 0: tm(3, 1) = 0
tm(3, 2) = 0: tm(3, 3) = 1

Debug.Print "MS Count " & ThisDrawing.ModelSpace.Count

startTime = VBA.Timer

Dim ent As AcadEntity
Dim iterator As AcadEntity

For Each iterator In ThisDrawing.ModelSpace

If TypeOf iterator Is AcadLine Or _
TypeOf iterator Is AcadMText Then
Set ent = iterator.Copy()
ent.TransformBy tm
End If

Next iterator

endTime = VBA.Timer

Debug.Print endTime - startTime
Debug.Print "MS Count " & ThisDrawing.ModelSpace.Count

End Sub
[/code]




"Laurie Comerford" wrote in message
news:5672536@discussion.autodesk.com...
Hi Paul,

Grabbing some sample code from the help system I ended up with:

Sub TestTransformBy()
Dim oEnt As AcadEntity
Dim oEntDup As AcadEntity
Dim PtStart(0 To 2) As Double
Dim i As Integer
Dim vPt As Variant
Dim lTmp As Long
Dim ssObjects As AcadSelectionSet
Dim TimeStart, TimeEnd
Dim transMat(0 To 3, 0 To 3) As Double
transMat(0, 0) = 1#: transMat(0, 1) = 0#: transMat(0, 2) = 0#:
transMat(0, 3) = 10#
transMat(1, 0) = 0#: transMat(1, 1) = 1#: transMat(1, 2) = 0#:
transMat(1, 3) = 0#
transMat(2, 0) = 0#: transMat(2, 1) = 0#: transMat(2, 2) = 1#:
transMat(2, 3) = 0#
transMat(3, 0) = 0#: transMat(3, 1) = 0#: transMat(3, 2) = 0#:
transMat(3, 3) = 1#
If SelectObjectsOnLayer(ssObjects, "LINE,MTEXT", "*") > 0 Then
TimeStart = 60 * Val(Format(Time, "MM")) + Val(Format(Time, "SS.SSS"))
For Each oEnt In ssObjects
For i = 1 To 1000
Set oEntDup = oEnt.Copy
oEntDup.TransformBy (transMat)
Next i
Next
TimeEnd = 60 * Val(Format(Time, "MM")) + Val(Format(Time, "SS.SSS"))
Debug.Print "1000 Lines and Mtext Items with TransformBy ",
Format(TimeEnd - TimeStart, "#0.0"); "seconds"
End If
End Sub ' ssTest()


For three runs in a drawing containing one line and one MText item this
reported. After each run I simply used the Undo command to remove the new
data.

1000 Lines and Mtext Items with TransformBy 4.0seconds
1000 Lines and Mtext Items with TransformBy 4.0seconds
1000 Lines and Mtext Items with TransformBy 4.0seconds


As it seemed significantly slower for the same data set on my computer I ran
the other methods again with the following results.

1000 Lines and Mtext Items with move 4.0seconds
1000 Lines and Mtext Items with move 4.0seconds
1000 Lines and Mtext Items with move 4.0seconds

1000 Lines and Mtext Items with Original code 2.0seconds
1000 Lines and Mtext Items with Original code 2.0seconds
1000 Lines and Mtext Items with Original code 2.0seconds

The only difference between when the first code was run and new is time
elapsed with AutoCAD open and that there is another 3Mb drawing open

Original Reports
1000 Lines and Mtext Items with entity.move 2.96875 seconds
1000 Lines and Mtext Items with entity.move 2.859375 seconds
1000 Lines and Mtext Items with entity.move 2.984375 seconds

1000 Lines and Mtext Items with Original code 1.609375 seconds
1000 Lines and Mtext Items with Original code 1.65625 seconds
1000 Lines and Mtext Items with Original code 1.609375 seconds

I'd be interested to see the results from your computer as there is nearly a
ten times difference in the output.
Also, my time measurement is more suited to comparisons on one computer than
anything else.

I'm running this in Civil 3D R2008. Although for comparisons with my other
times, that should be irrelevant.

I've never had cause to write code to move objects previously other than for
changing the insertion point of my test doughnut to highlight the point I've
just computed when I'm doing complex geometry and de-bugging. In that type
of code, setting the insertion to a computed point is the obvious answer.


--

Laurie Comerford
CADApps
www.cadapps.com.au
www.civil3Dtools.com

Sub TestTransformBy()
Dim oEnt As AcadEntity

Dim PtStart(0 To 2) As Double
Dim i As Integer
Dim vPt As Variant
Dim lTmp As Long
Dim ssObjects As AcadSelectionSet
Dim TimeStart, TimeEnd
Dim transMat(0 To 3, 0 To 3) As Double
transMat(0, 0) = 1#: transMat(0, 1) = 0#: transMat(0, 2) = 0#:
transMat(0, 3) = 10#
transMat(1, 0) = 0#: transMat(1, 1) = 1#: transMat(1, 2) = 0#:
transMat(1, 3) = 0#
transMat(2, 0) = 0#: transMat(2, 1) = 0#: transMat(2, 2) = 1#:
transMat(2, 3) = 0#
transMat(3, 0) = 0#: transMat(3, 1) = 0#: transMat(3, 2) = 0#:
transMat(3, 3) = 1#
If SelectObjectsOnLayer(ssObjects, "LINE,MTEXT", "*") > 0 Then
TimeStart = Timer
For Each oEnt In ssObjects
For i = 1 To 1000
Set oEnt = oEnt.Copy
oEnt.TransformBy (transMat)
Next i
Next
TimeEnd = Timer
Debug.Print "1000 Lines and Mtext Items with TransformBy ",
TimeEnd - TimeStart; "seconds"
End If
End Sub ' ssTest()
"Paul Richardson" wrote in message
news:5672502@discussion.autodesk.com...
>actually TransformBy is a property... entity.TransformBy

not it's NOT... I was right the first time. WOW! Anyway it's FAST.

Message 17 of 20
Anonymous
in reply to: Anonymous

Every time you reply to one of my posts, you
achieve little other than to make a complete
fool of yourself, and in the process, do great harm
to the reputation of the professional organization
you affiliate yourself with in your signature.

What a pathetic shame.

When you factor in all of the conditional branching
that must be done to accommodate every possible
type of entity, rather than only lines and MText,
then the code runs much slower than just calling
Move() on each Entity.

So, saying that garbage you posted is faster than
whatever, because you deliberately limited the
scope of the types involved to only lines and mtext,
rather than testing with all possible types of entities,
and with the conditional branching and dedicated
move function needed for each type of entity, is than
further demonstrating a complete lack of programming
skill.

And for the benefit of others who are reading this,
In object oriented programming, with an object
model and classes that support methods like Move()
or TransformBy(), you are supposed to use them,
because it allows your code to operate on any type
of entity, without regards for what type of entity it
is or whether you know anything about it, other than
that it is an entity.

Hence, if you use the Move() (or TransformBy) methods,
your code will support and move any type of entity that
can exist in a drawing, including custom objects that
you have no knowledge of at all.

That's the main problem with what Laurie is doing
(writing code to move each type of entity he knows
about, and hence, only supports the types of objects
he writes the code to move).

Now, in what is little other than a pathetic attempt to
save face, Laurie is trying to mislead you into believing
that performance is what matters, as opposed to sound
coding practices and writing code the right way - that
allows it to automatically support any and all types of
entities, including those Laurie does not even know exist.

How sad.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com
Message 18 of 20
Anonymous
in reply to: Anonymous

Hi Paul. The Move() method calls transformBy() internally,
and is just a sugar-coated wrapper for it, that eliminates
the need to construct the matrix manually.

However, TransformBy can be more effecient when you
need to move many objects by the same displacement,
since the matrix only needs to be constructed once.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

"Paul Richardson" wrote in message news:5672465@discussion.autodesk.com...
try TransformBy method. Copied 2000 entities in 0.421875 seconds...

wrote in message news:5671345@discussion.autodesk.com...
I have written a VB app that needs to retrieve specific entities (sometimes
over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities
transforming them one by one OR...

put them in a selection set and then execute the Copy command via
sendcommand.

I would have tried this myself but I don't understand how to use the
selection set I added the entities to as part of the SENDCOMMAND verbage or
if there is a way to 'select' them via code before using the Sendcommand
"Copy"

Any and all input on this issue will be greatly appreciated... I don't know
how many more times I can bang my head against the wall without it or the
wall being damaged. 🙂
Message 19 of 20
Anonymous
in reply to: Anonymous

Cool - Thanks.
"Tony Tanzillo" wrote in message
news:5672673@discussion.autodesk.com...
Hi Paul. The Move() method calls transformBy() internally,
and is just a sugar-coated wrapper for it, that eliminates
the need to construct the matrix manually.

However, TransformBy can be more effecient when you
need to move many objects by the same displacement,
since the matrix only needs to be constructed once.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

"Paul Richardson" wrote in message
news:5672465@discussion.autodesk.com...
try TransformBy method. Copied 2000 entities in 0.421875 seconds...

wrote in message news:5671345@discussion.autodesk.com...
I have written a VB app that needs to retrieve specific entities (sometimes
over 200 at a time) and transform (copy) them to a new location via code.

So my question is... Is it faster to simply cycle thru the entities
transforming them one by one OR...

put them in a selection set and then execute the Copy command via
sendcommand.

I would have tried this myself but I don't understand how to use the
selection set I added the entities to as part of the SENDCOMMAND verbage or
if there is a way to 'select' them via code before using the Sendcommand
"Copy"

Any and all input on this issue will be greatly appreciated... I don't know
how many more times I can bang my head against the wall without it or the
wall being damaged. 🙂
Message 20 of 20
Anonymous
in reply to: Anonymous

I don’t agree: in my opinion Object.move fromPoint toPoint is the simple way to perform a single translation, no matter how many objects you have to move. One needs transformation matrices for slightly more complex transformations (that is translations with rotations), particularly when you need to transform many copies of the same object. I don’t understand what you mean with “to construct the matrix manually”. In my experience it’s a nonsense to use a sort of constant matrix, calculated – as you say – “manually”; I for one make the program calculate the matrix, staring from two or three picked points.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost