Source code for pyautocad.api

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    pyautocad.api
    ~~~~~~~~~~~~~~~

    Main AutoCAD automation object.

    :copyright: (c) 2012 by Roman Haritonov.
    :license: BSD, see LICENSE.txt for more details.
"""

__all__ = ['Autocad', 'ACAD']

import logging
import comtypes
import glob
import os
try:
    import comtypes.client
    # generate modules for work with ACAD constants
    for pattern in ("acax*enu.tlb", "axdb*enu.tlb"):
        pattern = os.path.join(
            r"C:\Program Files\Common Files\Autodesk Shared",
            pattern
        )
        tlib = glob.glob(pattern)[0]
        comtypes.client.GetModule(tlib)
    import comtypes.gen.AutoCAD as ACAD
except Exception:
    # we are under readthedocs.org and need to mock this
    ACAD = None

import pyautocad.types
from pyautocad.compat import basestring, xrange

logger = logging.getLogger(__name__)


[docs]class Autocad(object): """Main AutoCAD Automation object """ def __init__(self, create_if_not_exists=False, visible=True): """ :param create_if_not_exists: if AutoCAD doesn't run, then new instanse will be crated :param visible: new AutoCAD instance will be visible if True (default) """ self._create_if_not_exists = create_if_not_exists self._visible = visible self._app = None @property def app(self): """Returns active :class:`AutoCAD.Application` if :class:`Autocad` was created with :data:`create_if_not_exists=True`, it will create :class:`AutoCAD.Application` if there is no active one """ if self._app is None: try: self._app = comtypes.client.GetActiveObject('AutoCAD.Application', dynamic=True) except WindowsError: if not self._create_if_not_exists: raise self._app = comtypes.client.CreateObject('AutoCAD.Application', dynamic=True) self._app.Visible = self._visible return self._app @property def doc(self): """ Returns `ActiveDocument` of current :attr:`Application`""" return self.app.ActiveDocument #: Same as :attr:`doc` ActiveDocument = doc #: Same as :attr:`app` Application = app @property def model(self): """ `ModelSpace` from active document """ return self.doc.ModelSpace
[docs] def iter_layouts(self, doc=None, skip_model=True): """Iterate layouts from *doc* :param doc: document to iterate layouts from if `doc=None` (default), :attr:`ActiveDocument` is used :param skip_model: don't include :class:`ModelSpace` if `True` """ if doc is None: doc = self.doc for layout in sorted(doc.Layouts, key=lambda x: x.TabOrder): if skip_model and not layout.TabOrder: continue yield layout
[docs] def iter_objects(self, object_name_or_list=None, block=None, limit=None, dont_cast=False): """Iterate objects from `block` :param object_name_or_list: part of object type name, or list of it :param block: Autocad block, default - :class:`ActiveDocument.ActiveLayout.Block` :param limit: max number of objects to return, default infinite :param dont_cast: don't retrieve best interface for object, may speedup iteration. Returned objects should be casted by caller """ if block is None: block = self.doc.ActiveLayout.Block object_names = object_name_or_list if object_names: if isinstance(object_names, basestring): object_names = [object_names] object_names = [n.lower() for n in object_names] count = block.Count for i in xrange(count): item = block.Item(i) # it's faster than `for item in block` if limit and i >= limit: return if object_names: object_name = item.ObjectName.lower() if not any(possible_name in object_name for possible_name in object_names): continue if not dont_cast: item = self.best_interface(item) yield item
[docs] def iter_objects_fast(self, object_name_or_list=None, container=None, limit=None): """Shortcut for `iter_objects(dont_cast=True)` Shouldn't be used in normal situations """ return self.iter_objects(object_name_or_list, container, limit, dont_cast=True)
[docs] def find_one(self, object_name_or_list, container=None, predicate=None): """Returns first occurance of object which match `predicate` :param object_name_or_list: like in :meth:`iter_objects` :param container: like in :meth:`iter_objects` :param predicate: callable, which accepts object as argument and returns `True` or `False` :returns: Object if found, else `None` """ if predicate is None: predicate = bool for obj in self.iter_objects(object_name_or_list, container): if predicate(obj): return obj return None
[docs] def best_interface(self, obj): """ Retrieve best interface for object """ return comtypes.client.GetBestInterface(obj)
[docs] def prompt(self, text): """ Prints text in console and in `AutoCAD` prompt """ print(text) self.doc.Utility.Prompt(u"%s\n" % text)
[docs] def get_selection(self, text="Select objects"): """ Asks user to select objects :param text: prompt for selection """ self.prompt(text) try: self.doc.SelectionSets.Item("SS1").Delete() except Exception: logger.debug('Delete selection failed') selection = self.doc.SelectionSets.Add('SS1') selection.SelectOnScreen() return selection
#: shortcut for :func:`pyautocad.types.aDouble` aDouble = staticmethod(pyautocad.types.aDouble) #: shortcut for :func:`pyautocad.types.aInt` aInt = staticmethod(pyautocad.types.aInt) #: shortcut for :func:`pyautocad.types.aShort` aShort = staticmethod(pyautocad.types.aShort)