Author Topic: Deep Cloning  (Read 4692 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Deep Cloning
« on: July 24, 2009, 05:46:23 PM »
I am in the middle of trying to figure out how to add existing objects to a block defintion through VL.

I have stumbled across this:

http://www.theswamp.org/index.php?topic=29366.0

And I see that LE uses vla-copyobjects.

After reading up on this function, I see it uses something called "deep cloning".

What, may I ask, is that?

Lee

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Re: Deep Cloning
« Reply #1 on: July 24, 2009, 06:09:36 PM »
On this same topic, I have tried to make the block using this method, but can't seem to get it to work. I keep getting an error: "Invalid Owner Object".

Here is the current method I am trying:

Code: [Select]
      (vla-copyobjects doc
        (vlax-make-variant
          (vlax-safearray-fill
            (vlax-make-safearray
              vlax-vbObject (cons 0 (1- (length bLst)))) bLst))
            (setq bdef
              (vla-add
                (vla-get-Blocks doc)
                  (vlax-3D-point pt) "NewBlock"))

Where bLst is a list of VLA-Objects, doc is the ActiveDocument.

I have also tried this:

Code: [Select]

      (vla-copyobjects doc
        (vlax-make-variant
          (vlax-safearray-fill
            (vlax-make-safearray
              vlax-vbObject (cons 0 (1- (length bLst)))) bLst))
        (vlax-make-variant
          (vlax-safearray-fill
            (vlax-make-safearray
              vlax-vbObject '(0 . 0))
            (setq bdef
              (vla-add
                (vla-get-Blocks doc)
                  (vlax-3D-point pt) "NewBlock")))))

Also, with no luck.

Any help is appreciated.

Lee

T.Willey

  • Needs a day job
  • Posts: 5213
Re: Deep Cloning
« Reply #2 on: July 24, 2009, 06:20:42 PM »
This works ( I hate dealing with variants in Lisp, it's unnatural ).

Code: [Select]
(vlax-invoke
    (vla-get-Activedocument (vlax-get-Acad-Object))
    'CopyObjects
    (list (vlax-ename->vla-object (car (entsel))))
    (vlax-invoke
        (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-Acad-Object)))
        'Add
        '(0. 0. 0.)
        "Testing"
    )
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5213
Re: Deep Cloning
« Reply #3 on: July 24, 2009, 06:24:25 PM »
Deep cloning to me is coping on the lowest level.  If you deep clone a block, then you have to copy all the objects that make up the object.  I think deep cloning only really refers to complex entities, but I know nothing about it, so that it with a grain of salt.  You might do better to search the .Net or Arx groups.  Someone might have posted a good explanation in there.  Search here and the Adesk group.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Re: Deep Cloning
« Reply #4 on: July 24, 2009, 06:26:25 PM »
Thanks Tim,

Using your idea, I tried this:

Code: [Select]
     (vlax-invoke doc 'copyobjects bLst
        (vlax-invoke
          (vla-get-Blocks doc) 'Add
            (vlax-3D-point pt) "NewBlock"))

But I got the Error: "Exception Occurred".

Would it make a difference what my objects are?

For example, the variable bLst looks like this:

Code: [Select]
(#<VLA-OBJECT IAcadAttribute 186894ec> #<VLA-OBJECT IAcadAttribute 1868956c>
#<VLA-OBJECT IAcadAttribute 186895ec> #<VLA-OBJECT IAcadAttribute 1868936c>
#<VLA-OBJECT IAcadAttribute 186893ec> #<VLA-OBJECT IAcadAttribute 1868946c>
#<VLA-OBJECT IAcadAttribute 1868906c> #<VLA-OBJECT IAcadAttribute 1868926c>
#<VLA-OBJECT IAcadAttribute 186892ec> #<VLA-OBJECT IAcadAttribute 18688fec>
#<VLA-OBJECT IAcadAttribute 1868916c> #<VLA-OBJECT IAcadAttribute 18688f6c>
#<VLA-OBJECT IAcadAttribute 1814a964> #<VLA-OBJECT IAcadAttribute 1814ae64>
#<VLA-OBJECT IAcadAttribute 1814b2e4> #<VLA-OBJECT IAcadAttribute 185e7f7c>
#<VLA-OBJECT IAcadLWPolyline 0e6af944> #<VLA-OBJECT IAcadAttribute 185e7f7c>
#<VLA-OBJECT IAcadLWPolyline 0e6af944> #<VLA-OBJECT IAcadAttribute 185e7f7c>
#<VLA-OBJECT IAcadLWPolyline 0e6af944> #<VLA-OBJECT IAcadAttribute 185e7f7c>
#<VLA-OBJECT IAcadLWPolyline 0e6af944> #<VLA-OBJECT IAcadAttribute 185e7f7c>
#<VLA-OBJECT IAcadLWPolyline 0e6af944> #<VLA-OBJECT IAcadLWPolyline 18303f3c>
#<VLA-OBJECT IAcadLWPolyline 183031bc> #<VLA-OBJECT IAcadLWPolyline 1830315c>
#<VLA-OBJECT IAcadLWPolyline 18302cdc> #<VLA-OBJECT IAcadLWPolyline 18302bbc>
#<VLA-OBJECT IAcadLWPolyline 18302dfc> #<VLA-OBJECT IAcadLWPolyline 1830357c>
#<VLA-OBJECT IAcadLWPolyline 1830585c>)

Thanks for your response Tim, you are very helpful  :-)

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Re: Deep Cloning
« Reply #5 on: July 24, 2009, 06:28:58 PM »
Deep cloning to me is coping on the lowest level.  If you deep clone a block, then you have to copy all the objects that make up the object.  I think deep cloning only really refers to complex entities, but I know nothing about it, so that it with a grain of salt.  You might do better to search the .Net or Arx groups.  Someone might have posted a good explanation in there.  Search here and the Adesk group.

I found this from a Java site, I suppose the same thing applies for LISP:

http://technologiquepanorama.wordpress.com/2009/01/11/what-is-deep-copy/

T.Willey

  • Needs a day job
  • Posts: 5213
Re: Deep Cloning
« Reply #6 on: July 24, 2009, 06:38:37 PM »
Thanks Tim,

Using your idea, I tried this:

Code: [Select]
     (vlax-invoke doc 'copyobjects bLst
        (vlax-invoke
          (vla-get-Blocks doc) 'Add
            (vlax-3D-point pt) "NewBlock"))

But I got the Error: "Exception Occurred".

When you use ' vlax-invoke ' you use lists, so no need to convert the point to a ' vlax-3d-point '.  Take that call out, and it should work.

As far as the deep cloning, I would think the same principal would apply to most languages.

You're welcome.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Re: Deep Cloning
« Reply #7 on: July 24, 2009, 06:40:43 PM »
Ahh, of course... the 3D-point is a variant... the "unnatural" type :P

School-boy error  :-)

Thanks Tim, will give it a go  :-)

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Re: Deep Cloning
« Reply #8 on: July 24, 2009, 06:43:57 PM »
Oh dear, I can't believe how much trouble I am having with this code  :-P

I am using this:

Code: [Select]
      (vlax-invoke doc 'copyobjects bLst
        (vlax-invoke
          (vla-get-Blocks doc) 'Add pt "NewBlock"))

But I still seem to get this:

Code: [Select]
** Error: AutoCAD.Application: Invalid owner object **

But, I can't see what I am doing that is different to your example  :|

T.Willey

  • Needs a day job
  • Posts: 5213
Re: Deep Cloning
« Reply #9 on: July 24, 2009, 06:55:30 PM »
How are you getting the objects within the list?  If you post the whole code maybe we can get a better idea of why it's not working as is.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Joe Burke

  • Guest
Re: Deep Cloning
« Reply #10 on: July 25, 2009, 04:58:31 AM »
May I suggest it's not a good idea to nest functions while trying to troubleshoot a problem like this. Add the block first and assign it to a variable. Make sure that works as expected. Then do CopyObjects.

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Re: Deep Cloning
« Reply #11 on: July 25, 2009, 08:38:04 AM »
May I suggest it's not a good idea to nest functions while trying to troubleshoot a problem like this. Add the block first and assign it to a variable. Make sure that works as expected. Then do CopyObjects.

Thanks Joe, I have tried this but still no luck :-(

VovKa

  • Swamp Rat
  • Posts: 1118
  • Ukraine
Re: Deep Cloning
« Reply #12 on: July 25, 2009, 10:02:53 AM »
abstract from the help file on CopyObjects method
Quote
Objects

Variant (array of objects); input-only
The array of primary objects to be copied. All the objects must have the same owner, and the owner must belong to the database or document that is calling this method.

Lee Mac

  • Seagull
  • Posts: 12241
  • London, England
Re: Deep Cloning
« Reply #13 on: July 25, 2009, 10:08:57 AM »
haha... of course... I am ripping Objects from block definitions... Thanks VovKa!

Jürg Menzi

  • Swamp Rat
  • Posts: 597
  • Oberegg, Switzerland
Re: Deep Cloning
« Reply #14 on: October 07, 2010, 08:00:36 AM »
This works ( I hate dealing with variants in Lisp, it's unnatural ).

Thanks Tim, you helped me out to create a VBA solution based on your code:
Code: [Select]
'Function MeCloneBlockRef
'Description:
'     Clones a Block reference into a new Block definition.
'   Arguments:
'     - oOldBlk = Existing Block reference
'     - sNewNme = New Block name
'     - oNewBlk = New Block definition
'   Return:
'     - True = Success
'     - False = Error
'   Remarks:
'     - Based on a VisualLISP code from Tim Willey, San Fernando Valley CA, USA
'
Public Function MeCloneBlockRef(ByVal oOldBlk As AcadBlockReference, ByVal sNewNme As String, oNewBlk As AcadBlock) As Boolean
  Dim aTmpBlk(0) As Object
  Dim aNulPnt(0 To 2) As Double
  On Error Resume Next
  With ThisDrawing
    .Blocks.Item sNewNme
    If Err.Number <> 0 Then 'If Block definition doesn't exist...
      Err.Clear
      aTmpBlk(0) = oOldBlk
      aNulPnt(0) = 0#: aNulPnt(1) = 0#: aNulPnt(2) = 0#
      .CopyObjects aTmpBlk, .Blocks.Add(aNulPnt, sNewNme)
      Set oNewBlk = .Blocks.Item(sNewNme)
      MeCloneBlockRef = True
    End If
  End With
End Function

Reason:
ObjectDBX for VBA isn't supported on 64Bit OS.

Cheers
A computer's human touch is its unscrupulousness!
MENZI ENGINEERING GmbH
Current A2k14... A2k18 - Start R2.18