Playing with ActiveX, Python and Variant.

in #programming7 years ago

This is my first post in Steemit, I thought to write the first post regarding DGB but, due to recent issues that I met during my job, I decide to post a little trick about ActiveX/COM and how to use variant array in Python.

Synopsis

Recently I had to write a script to automate a several operation in a several hundreds file of AutoCAD. I decided to use Python. In the usual way I'll code with VBA or Lisp but this time I would to try if there will be any advantage using python and ... it was!!!!

To get started

First of all I looked for a Python module (i.e. library) that "library aimed to simplify writing ActiveX Automation scripts for AutoCAD with Python", oh oh but it is pyautocad and it is what I need. After install it I start to code.

AutoCAD application wrapper

The first is a simple wrapper that instantiate the COM server object o AutoCAD:

from pyautocad import *

def getAutocadApplication(create_if_not_exists=True):
    ''' Return the Autocad application Object'''

    acad = Autocad(create_if_not_exists, visible=True)
    if acad is None:
        return None
    else:
        return acad.app

Loading DWG and the problem with variant array.

The code to load a DWG document is very simple:

  acadApp = getAutocadApplication()
  acadDoc = acadApp.Documents.Open(path.join(source_path, filename))

and to retrieve the BoundingBox, from AutoCAD ActiveX documentation:

# Signature

object.GetBoundingBox MinPoint, MaxPointobject

[object]
  Type: All drawing objects, AttributeReference, Dimension
  The objects this method applies to.

[MinPoint[]
  Access: Output-only
  Type: Variant (three-element array of doubles)
  The 3D WCS coordinates specifying the minimum point of the object's bounding box.

[MaxPoint]
  Access: Output-only
  Type: Variant (three-element array of doubles)
  The 3D WCS coordinates specifying the maximum point of the object's bounding box.

and my question is: How to pass an variant array to a COM object (in Python)?

Solution

After several hours passed to search in the Web (see Contributors below) I implemented the follow:

def GetBoundingBox(entity):
    # Create 3-d 'Variant' array of 'd'-ouble
    A = automation.VARIANT(array('d', [0,0,0]))
    B = automation.VARIANT(array('d', [0,0,0]))
    # Get the reference / address
    vA = byref(A)
    vB = byref(B)
    # Call the method from COM object
    entity.GetBoundingBox(vA, vB)
    # Return two points as 3-d
    return (A.value, B.value)

and this is the solution with the amazing NumPy module:

def GetBoundingBox(entity):
    # Create 3-d 'Variant' array of 'd'-ouble
    A = np.Array([0,0,0], dtype=double)
    B = np.Array([0,0,0], dtype=double)
    # Call the method from COM object
    entity.GetBoundingBox(A, B)
    # Return two points as 3-d
    return (A, B)

Contributors

Sort:  

Congratulations @d-man! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You got your First payout

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

hey d-man, I saw that you downvoted my posts. I understand that you thought you did the right thing, but please(!) understand that I'm not a pedophile and this a huge misunderstanding. I've written a short post about this whole sitation. Would you mind reading through it? https://steemit.com/steemit/@therealwolf/i-feel-humiliated-and-bullied

I don't like to be marked as something I am not . Thank you!!

Congratulations @d-man! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of comments

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Congratulations @d-man! You have received a personal award!

1 Year on Steemit
Click on the badge to view your Board of Honor.

Do not miss the last post from @steemitboard!


Participate in the SteemitBoard World Cup Contest!
Collect World Cup badges and win free SBD
Support the Gold Sponsors of the contest: @good-karma and @lukestokes


Do you like SteemitBoard's project? Then Vote for its witness and get one more award!

Congratulations @d-man! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

The Steem community has lost an epic member! Farewell @woflhart!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!