Element Wrappers

Element

Element Model Wrappers provide a consitent interface for acccessing parameters and properties of commonly used elements.

class rpw.db.Element(element, doc=None)

Bases: rpw.base.BaseObjectWrapper

Inheriting from element extends wrapped elements with a new parameters attribute, well as the unwrap() method inherited from the BaseObjectWrapper class.

It can be created by instantiating rpw.db.Element , or one of the helper static methods shown below.

Most importantly, all other Element-related classes inhert from this class so it can provide parameter access.

>>> element = rpw.db.Element(SomeElement)
>>> element = rpw.db.Element.from_id(ElementId)
>>> element = rpw.db.Element.from_int(Integer)
>>> wall = rpw.db.Element(RevitWallElement)
>>> wall.Id
>>> wall.parameters['Height'].value
10.0

The Element Constructor can be used witout specifying the exact class. On instantiation, it will attempt to map the type provided, if a match is not found, an Element will be used. If the element does not inherit from DB.Element, and exception is raised.

>>> wall_instance = rpw.db.Element(SomeWallInstance)
>>> type(wall_instance)
'rpw.db.WallInstance'
>>> wall_symbol = rpw.db.Element(SomeWallSymbol)
>>> type(wall_symbol)
'rpw.db.WallSymbol'
parameters

ParameterSet – Access ParameterSet class.

parameters.builtins

ParameterSet – BuitIn ParameterSet object

unwrap()

Wrapped Revit Reference

__init__(element, doc=None)

Main Element Instantiation

>>> wall = rpw.db.Element(SomeElementId)
<rpw: WallInstance % DB.Wall >
>>> wall.parameters['Height']
10.0
>>> wall.parameters.builtins['WALL_LOCATION_LINE']
1
Parameters:element (Element Reference) – Can be DB.Element, DB.ElementId, or int.
Returns:Instance of Wrapped Element.
Return type:Element
static __new__(element, **kwargs)

Factory Constructor will chose the best Class for the Element. This function iterates through all classes in the rpw.db module, and will find one that wraps the corresponding class. If and exact match is not found Element is used

classmethod collect(**kwargs)

Collect all elements of the wrapper, using the default collector.

Collector will use default params (ie: Room {'of_category': 'OST_rooms'}). These can be overriden by passing keyword args to the collectors call.

>>> rooms = rpw.db.Rooms.collect()
[<rpw:Room % DB.Room | Room:1>]
>>> rooms = rpw.db.Area.collect()
[<rpw:Area % DB.Area | Rentable:30.2>]
>>> rooms = rpw.db.WallInstance.collect(level="Level 1")
[<rpw:WallInstance % DB.Wall symbol:Basic Wall>]
delete()

Deletes Element from Model

static from_id(element_id, doc=None)

Instantiate Element from an ElementId

Parameters:
  • id (ElementId) – ElementId of Element to wrap
  • doc (DB.Document, optional) – Document of Element [default: revit.doc]
Returns:

Wrapped rpw.db.Element instance

Return type:

(Element)

static from_int(id_int, doc=None)

Instantiate Element from an Integer representing and Id

Parameters:
  • id (int) – ElementId of Element to wrap
  • doc (DB.Document, optional) – Document of Element [default: revit.doc]
Returns:

Wrapped rpw.db.Element instance

Return type:

(Element)

static from_list(elements, doc=None)

Instantiate Elements from a list of DB.Element instances

Parameters:elements ([DB.Element,]) – List of elements
Returns:List of rpw.db.Element instances
Return type:(list)
in_assembly

Returns True if element is inside an AssemblyInstance

type

Get’s Element Type using the default GetTypeId() Method. For some Elements, this is the same as element.Symbol or wall.WallType

Parameters:doc (DB.Document, optional) – Document of Element [default: revit.doc]
Returns:Wrapped rpw.db.Element element type
Return type:(Element)

Instance

class rpw.db.FamilyInstance(element, doc=None)

Bases: rpw.db.element.Element

DB.FamilyInstance Wrapper

>>> instance = rpw.db.Element(SomeFamilyInstance)
<rpw:FamilyInstance % DB.FamilyInstance | name:72" x 36">
>>> instance.symbol.name
'72" x 36"'
>>> instance.family
<RPW_Family:desk>
>>> instance.siblings
[<rpw:FamilyInstance % DB.FamilyInstance | name:72" x 36">, ... ]
Attribute:
_revit_object (DB.FamilyInstance): Wrapped DB.FamilyInstance
category

Wrapped DB.Category of the DB.Symbol

family

Wrapped DB.Family of the DB.FamilyInstance

siblings

Other DB.FamilyInstance of the same DB.FamilySymbol

symbol

Wrapped DB.FamilySymbol of the DB.FamilyInstance

Symbol

class rpw.db.FamilySymbol(element, doc=None)

Bases: rpw.db.element.Element

DB.FamilySymbol Wrapper

>>> symbol = rpw.db.Element(SomeSymbol)
<rpw:FamilySymbol % DB.FamilySymbol | name:72" x 36">
>>> instance.symbol.name
'72" x 36"'
>>> instance.family
<rpw:Family % DB.Family | name:desk>
>>> instance.siblings
<rpw:Family % DB.Family | name:desk>, ... ]
Attribute:
_revit_object (DB.FamilySymbol): Wrapped DB.FamilySymbol
category

ReturnsCategory – Wrapped DB.Category of the symbol

family

ReturnsFamily – Wrapped DB.Family of the symbol

instances

Returns – [DB.FamilyInstance] – List of model instances of the symbol (unwrapped)

name

Returns the name of the Symbol

siblings

Returns – [DB.FamilySymbol] – List of symbol Types of the same Family (unwrapped)

Family

class rpw.db.Family(element, doc=None)

Bases: rpw.db.element.Element

DB.Family Wrapper

Attribute:
_revit_object (DB.Family): Wrapped DB.Family
category

ReturnsCategory – Wrapped DB.Category of the Family

instances

Returns – [DB.FamilyInstance] – List of model instances in this family (unwrapped)

name

Returnsstr – name of the Family

siblings

Returns – [DB.Family] – List of Family elements in the same category (unwrapped)

symbols

Returns – [DB.FamilySymbol] – List of Symbol Types in the family (unwrapped)

Category

class rpw.db.Category(revit_object, enforce_type=True)

Bases: rpw.base.BaseObjectWrapper

DB.Category Wrapper

Attribute:
_revit_object (DB.Family): Wrapped DB.Category
_builtin_enum

Returns BuiltInCategory of the Category

families

Returns – [DB.Family] – List of Family elements in this same category (unwrapped)

instances

Returns – [DB.FamilyInstance] – List of Symbol Instances in the Category (unwrapped)

name

Returns name of the Category

symbols

Returns – [DB.FamilySymbol] – List of Symbol Types in the Category (unwrapped)


Walls

Wall Element Tree Wrappers

Note

These classes inherit from the classes listed above, but make some adjustments to compensate for dissimilarities in in Wall Families.

When retrieving the FamilySymbol from an instance, and the Family from a Symbol, one might uses instance.Symbol and symbol.Family.

Unfortunately, this would not be the case with Wall Elements. A Wall Instance is actually a DB.Wall; the Family Type of a wall is not a DB.FamilySymbol type, but a DB.WallType; and instead of .Family, walls use .Kind.

These wrappers create a more consistent navigation by allowing to retrieve the “symbol” and “family” of a wall using: wall.symbol, and wall.family

>>> wall = rpw.db.Wall(SomeWallInstance)
>>> wall.symbol
<rpw: WallType % DB.WallType | type:Wall 1>
>>> wall.family
<rpw: WallKind % DB.WallKind | type:Basic 1>
class rpw.db.Wall(element, doc=None)

Bases: rpw.db.family.FamilyInstance

Inherits base FamilyInstance and overrides symbol attribute to get Symbol equivalent of Wall - WallType (GetTypeId)

category

Wrapped DB.Category of the DB.Wall

change_type(wall_type_reference)

Change Wall Type

Parameters:wall_type_reference (ElementId, WallType, str) – Wall Type Reference
class rpw.db.WallType(element, doc=None)

Bases: rpw.db.family.FamilySymbol, rpw.utils.mixins.ByNameCollectMixin

Inherits from FamilySymbol and overrides:
  • wall_kind() to get the Family equivalent of Wall (.Kind)
  • Uses a different method to get instances.
category

Wrapped DB.Category of the DB.Wall

instances

Returns all Instances of this Wall Types

wall_kind

Returns DB.Family of the Symbol

class rpw.db.WallKind(revit_object, enforce_type=True)

Bases: rpw.base.BaseObjectWrapper

Equivalent of Family but is Enumerator for Walls.

Can be Basic, Stacked, Curtain, Unknown

instances

Returns all Wall instances of this given Wall Kind

name

Retuns Pretty Name as shown on UI – Basic > Basic Wall

class rpw.db.WallCategory(revit_object, enforce_type=True)

Bases: rpw.db.family.Category

DB.Category Wall Category Wrapper

Attribute:
_revit_object (DB.Family): Wrapped DB.Category
families

Returns DB.WallKind elements in the category


Spatial Elements

Room Wrapper

class rpw.db.Room(element, doc=None)

Bases: rpw.db.element.Element

DB.Architecture.Room Wrapper Inherits from Element

>>> room = rpw.db.Room(SomeRoom)
<rpw:Room % DB.Architecture.Room | name:Office number:122>
>>> room.name
'Office'
>>> room.number
'122'
>>> room.is_placed
True
>>> room.is_bounded
True
Attribute:
_revit_object (DB.Architecture.Room): Wrapped DB.Architecture.Room
is_bounded

bool for whether Room is Bounded. Uses result of Room.Area attribute to define if room is Bounded.

is_placed

bool for whether Room is Placed. Uses result of Room.Location attribute to define if room is Placed.

name

Room Name as parameter ValueROOM_NAME built-in parameter

number

Room Number as parameter ValueROOM_NUMBER built-in parameter

Area Wrapper

class rpw.db.Area(element, doc=None)

Bases: rpw.db.spatial_element.Room

DB.Area Wrapper Inherits from Room

>>> area = rpw.db.Area(SomeArea)
<rpw:Area % DB.Area | name:USF area: 100.0>
>>> area.name
'Rentable'
>>> area.is_placed
True
>>> area.is_bounded
True
Attribute:
_revit_object (DB.Area): Wrapped DB.Area
area

Area – .Area attribute

name

Area Scheme Name – Area attribute parameter

scheme

Area Scheme – Wrapped Area Scheme

Area Scheme Wrapper

class rpw.db.AreaScheme(element, doc=None)

Bases: rpw.db.element.Element

DB.AreaScheme Wrapper Inherits from Element

>>> scheme = wrapped_room.scheme
<rwp:AreaScheme % DB.AreaScheme | name:USF>
>>> scheme.areas
[ < Autodesk.Revit.DB.Area>, ...]
>>> scheme.name
'USF'
Attribute:
_revit_object (DB.AreaScheme): Wrapped DB.AreaScheme
areas

Returns all Area Instances of this Area Scheme

name

Area Scheme Name – Area attribute parameter


Implementation


import inspect

import rpw
from rpw import revit, DB
from rpw.db.parameter import Parameter, ParameterSet
from rpw.base import BaseObjectWrapper
from rpw.exceptions import RpwException, RpwWrongStorageType
from rpw.exceptions import RpwParameterNotFound, RpwTypeError
from rpw.utils.logger import logger
from rpw.db.builtins import BicEnum, BipEnum


class Element(BaseObjectWrapper):
    """
    Inheriting from element extends wrapped elements with a new :class:`parameters`
    attribute, well as the :func:`unwrap` method inherited from the :any:`BaseObjectWrapper` class.

    It can be created by instantiating ``rpw.db.Element`` , or one of the helper
    static methods shown below.

    Most importantly, all other `Element-related` classes inhert from this class
    so it can provide parameter access.

    >>> element = rpw.db.Element(SomeElement)
    >>> element = rpw.db.Element.from_id(ElementId)
    >>> element = rpw.db.Element.from_int(Integer)

    >>> wall = rpw.db.Element(RevitWallElement)
    >>> wall.Id
    >>> wall.parameters['Height'].value
    10.0

    The ``Element`` Constructor can be used witout specifying the
    exact class. On instantiation, it will attempt to map the type provided,
    if a match is not found, an Element will be used.
    If the element does not inherit from DB.Element, and exception is raised.

    >>> wall_instance = rpw.db.Element(SomeWallInstance)
    >>> type(wall_instance)
    'rpw.db.WallInstance'
    >>> wall_symbol = rpw.db.Element(SomeWallSymbol)
    >>> type(wall_symbol)
    'rpw.db.WallSymbol'

    Attributes:

        parameters (:any:`ParameterSet`): Access :any:`ParameterSet` class.
        parameters.builtins (:any:`ParameterSet`): BuitIn :any:`ParameterSet` object

    Methods:
        unwrap(): Wrapped Revit Reference

    """

    _revit_object_class = DB.Element

    def __new__(cls, element, **kwargs):
        """
        Factory Constructor will chose the best Class for the Element.
        This function iterates through all classes in the rpw.db module,
        and will find one that wraps the corresponding class. If and exact
        match is not found :any:`Element` is used
        """
        defined_wrapper_classes = rpw.db.__all__

        _revit_object_class = cls._revit_object_class

        if element is None:
            raise RpwTypeError('Element or Element Child', 'None')

        # Ensure Wrapped Element is instance of Class Wrapper or decendent
        # Must also check is element because isinstance(Element, Element) is False
        if not isinstance(element, _revit_object_class):
            # or cls is not Element:
            raise RpwTypeError('DB.Element child', element.__class__.__name__)

        # TODO: OPtimize so if its right type, no need to iterate: rpw.db.Wall(wall)
        for wrapper_class in defined_wrapper_classes:
            class_name = wrapper_class.__name__
            if type(element) is getattr(wrapper_class, '_revit_object_class', None):
                # Found Mathing Class, Use Wrapper
                # print('Found Mathing Class, Use Wrapper: {}'.format(class_name))
                return super(Element, cls).__new__(wrapper_class, element, **kwargs)
        else:
            # Could Not find a Matching Class, Use Element if related
            if DB.Element in inspect.getmro(element.__class__):
                return super(Element, cls).__new__(cls, element, **kwargs)

        # No early return. Should not reach this point
        element_class_name = element.__class__.__name__
        raise RpwException('Factory does not support type: {}'.format(element_class_name))

    def __init__(self, element, doc=None):
        """
        Main Element Instantiation

        >>> wall = rpw.db.Element(SomeElementId)
        <rpw: WallInstance % DB.Wall >
        >>> wall.parameters['Height']
        10.0
        >>> wall.parameters.builtins['WALL_LOCATION_LINE']
        1

        Args:
            element (`Element Reference`): Can be ``DB.Element``, ``DB.ElementId``, or ``int``.

        Returns:
            :class:`Element`: Instance of Wrapped Element.

        """

        super(Element, self).__init__(element)
        self.doc = element.Document if doc is None else revit.doc
        if isinstance(element, DB.Element):
            # WallKind Inherits from Family/Element, but is not Element,
            # so ParameterSet fails. Parameters are only added if Element
            # inherits from element
            # NOTE: This is no longer the case. Verify if it can be removed
            self.parameters = ParameterSet(element)

    @property
    def type(self):
        """
        Get's Element Type using the default GetTypeId() Method.
        For some Elements, this is the same as ``element.Symbol`` or ``wall.WallType``

        Args:
            doc (``DB.Document``, optional): Document of Element [default: revit.doc]

        Returns:
            (``Element``): Wrapped ``rpw.db.Element`` element type

        """
        element_type_id = self._revit_object.GetTypeId()
        element_type = self._revit_object.Document.GetElement(element_type_id)
        return Element(element_type)

    @property
    def in_assembly(self):
        """ Returns True if element is inside an AssemblyInstance """
        if self._revit_object.AssemblyInstanceId.IntegerValue == -1:
            return False
        else:
            return True

    @classmethod
    def collect(cls, **kwargs):
        """ Collect all elements of the wrapper, using the default collector.

        Collector will use default params (ie: Room ``{'of_category': 'OST_rooms'}``).
        These can be overriden by passing keyword args to the collectors call.

        >>> rooms = rpw.db.Rooms.collect()
        [<rpw:Room % DB.Room | Room:1>]
        >>> rooms = rpw.db.Area.collect()
        [<rpw:Area % DB.Area | Rentable:30.2>]
        >>> rooms = rpw.db.WallInstance.collect(level="Level 1")
        [<rpw:WallInstance % DB.Wall symbol:Basic Wall>]

        """
        _collector_params = getattr(cls, '_collector_params', None)

        if _collector_params:
            kwargs.update(_collector_params)
            return rpw.db.Collector(**kwargs)
        else:
            raise RpwException('Wrapper cannot collect by class: {}'.format(cls.__name__))

    @staticmethod
    def from_int(id_int, doc=None):
        """
        Instantiate Element from an Integer representing and Id

        Args:
            id (``int``): ElementId of Element to wrap
            doc (``DB.Document``, optional): Document of Element [default: revit.doc]

        Returns:
            (``Element``): Wrapped ``rpw.db.Element`` instance
        """
        doc = revit.doc if doc is None else doc
        element_id = DB.ElementId(id_int)
        return Element.from_id(element_id, doc=doc)

    @staticmethod
    def from_id(element_id, doc=None):
        """
        Instantiate Element from an ElementId

        Args:
            id (``ElementId``): ElementId of Element to wrap
            doc (``DB.Document``, optional): Document of Element [default: revit.doc]

        Returns:
            (``Element``): Wrapped ``rpw.db.Element`` instance

        """
        doc = revit.doc if doc is None else doc
        element = doc.GetElement(element_id)
        return Element(element)

    @staticmethod
    def from_list(elements, doc=None):
        """
        Instantiate Elements from a list of DB.Element instances

        Args:
            elements (``[DB.Element,]``): List of elements

        Returns:
            (``list``): List of ``rpw.db.Element`` instances

        """
        doc = revit.doc if doc is None else doc
        return [Element(element) for element in elements]

    @staticmethod
    def Factory(element):
        # Depracated - For Compatibility Only
        msg = 'Element.Factory() has been depracated. Use Element()'
        logger.warning(msg)
        return Element(element)

    def delete(self):
        """ Deletes Element from Model """
        self.doc.Delete(self._revit_object.Id)

    def __repr__(self, data=None):
        if data is None:
            data = {}
        element_id = getattr(self._revit_object, 'Id', None)
        if element_id:
            data.update({'id': element_id})
        return super(Element, self).__repr__(data=data)

import rpw
from rpw import revit, DB
from rpw.db import Element
from rpw.db import FamilyInstance, FamilySymbol, Family, Category
from rpw.base import BaseObjectWrapper
from rpw.utils.logger import logger
from rpw.utils.coerce import to_element_id
from rpw.db.builtins import BipEnum
from rpw.exceptions import RpwTypeError, RpwCoerceError
from rpw.utils.mixins import ByNameCollectMixin


class Wall(FamilyInstance):
    """
    Inherits base ``FamilyInstance`` and overrides symbol attribute to
    get `Symbol` equivalent of Wall - WallType `(GetTypeId)`
    """

    _revit_object_category = DB.BuiltInCategory.OST_Walls
    _revit_object_class = DB.Wall
    _collector_params = {'of_class': _revit_object_class, 'is_type': False}

    def change_type(self, wall_type_reference):
        """
        Change Wall Type

        Args:
            wall_type_reference (``ElementId``, ``WallType``, ``str``): Wall Type Reference
        """
        wall_type = WallType.by_name_or_element_ref(wall_type_reference)
        wall_type_id = to_element_id(wall_type)
        self._revit_object.ChangeTypeId(wall_type_id)

    @property
    def symbol(self):
        return self.wall_type

    @property
    def wall_type(self):
        wall_type_id = self._revit_object.GetTypeId()
        wall_type = self.doc.GetElement(wall_type_id)
        return WallType(wall_type)

    @property
    def wall_kind(self):
        return self.wall_type.wall_kind

    @property
    def family(self):
        return self.wall_kind

    @property
    def category(self):
        """ Wrapped ``DB.Category`` of the ``DB.Wall`` """
        return WallCategory(self._revit_object.Category)


class WallType(FamilySymbol, ByNameCollectMixin):
    """
    Inherits from :any:`FamilySymbol` and overrides:
        * :func:`wall_kind` to get the `Family` equivalent of Wall `(.Kind)`
        * Uses a different method to get instances.
    """

    _revit_object_class = DB.WallType
    _collector_params = {'of_class': _revit_object_class, 'is_type': True}

    @property
    def family(self):
        return self.wall_kind

    @property
    def wall_kind(self):
        """ Returns ``DB.Family`` of the Symbol """
        return WallKind(self._revit_object.Kind)

    @property
    def instances(self):
        """ Returns all Instances of this Wall Types """
        bip = BipEnum.get_id('SYMBOL_NAME_PARAM')
        param_filter = rpw.db.ParameterFilter(bip, equals=self.name)
        return rpw.db.Collector(parameter_filter=param_filter,
                                **Wall._collector_params).wrapped_elements

    @property
    def siblings(self):
        return self.wall_kind.wall_types

    @property
    def category(self):
        """ Wrapped ``DB.Category`` of the ``DB.Wall`` """
        return WallCategory(self._revit_object.Category)


# class WallKind(Family):
class WallKind(BaseObjectWrapper):
    """
    Equivalent of ``Family`` but is Enumerator for Walls.

    Can be Basic, Stacked, Curtain, Unknown
    """

    _revit_object_class = DB.WallKind

    @property
    def name(self):
        """ Retuns Pretty Name as shown on UI: Basic > Basic Wall """
        # Same method as Family Works, but requires Code duplication
        # Since this should not inherit from Family.
        # Solution copy code or Mixin. Or return Enum Name:  'Basic'
        # This works but requires Lookup.
        # wall_type = self.wall_types[0]
        # return wall_type.parameters.builtins['SYMBOL_FAMILY_NAME_PARAM'].value
        # return '{} Wall'.format(self._revit_object.ToString())
        return self._revit_object.ToString()

    @property
    def symbols(self):
        return self.wall_types

    @property
    def wall_types(self):
        wall_types = rpw.db.Collector(**WallType._collector_params).wrapped_elements
        return [wall_type for wall_type in wall_types
                if wall_type.Kind == self._revit_object]

    @property
    def instances(self):
        """ Returns all Wall instances of this given Wall Kind"""
        instances = []
        for wall_type in self.wall_types:
            instances.extend(wall_type.instances)
        return instances

    @property
    def category(self):
        cat = DB.Category.GetCategory(revit.doc, DB.BuiltInCategory.OST_Walls)
        return WallCategory(cat)
        # wall_type = rpw.db.Collector(of_class=DB.WallType, is_type=True).first
        # return WallCategory(wall_type.Category)

    def __repr__(self):
        return super(WallKind, self).__repr__({'name': self.name})

class WallCategory(Category):
    """
    ``DB.Category`` Wall Category Wrapper

    Attribute:
        _revit_object (DB.Family): Wrapped ``DB.Category``
    """

    _revit_object_class = DB.Category

    @property
    def families(self):
        """ Returns ``DB.WallKind`` elements in the category """
        wall_kinds = []
        for member in dir(DB.WallKind):
            if type(getattr(DB.WallKind, member)) is DB.WallKind:
                wall_kind = WallKind(getattr(DB.WallKind, member))
                wall_kinds.append(wall_kind)
        return wall_kinds

import rpw
from rpw import revit, DB
from rpw.db import Element
from rpw.utils.logger import logger
from rpw.db.builtins import BipEnum


class Room(Element):
    """
    `DB.Architecture.Room` Wrapper
    Inherits from :any:`Element`

    >>> room = rpw.db.Room(SomeRoom)
    <rpw:Room % DB.Architecture.Room | name:Office number:122>
    >>> room.name
    'Office'
    >>> room.number
    '122'
    >>> room.is_placed
    True
    >>> room.is_bounded
    True

    Attribute:
        _revit_object (DB.Architecture.Room): Wrapped ``DB.Architecture.Room``
    """

    _revit_object_class = DB.Architecture.Room
    _revit_object_category = DB.BuiltInCategory.OST_Rooms
    _collector_params = {'of_category': _revit_object_category,
                         'is_not_type': True}

    @property
    def name(self):
        """ Room Name as parameter Value: ``ROOM_NAME`` built-in parameter"""
        # Note: For an unknown reason, roominstance.Name does not work on IPY
        return self.parameters.builtins['ROOM_NAME'].value

    @name.setter
    def name(self, value):
        self.parameters.builtins['ROOM_NAME'].value = value

    @property
    def number(self):
        """ Room Number as parameter Value: ``ROOM_NUMBER`` built-in parameter"""
        return self.parameters.builtins['ROOM_NUMBER'].value

    @number.setter
    def number(self, value):
        self.parameters.builtins['ROOM_NUMBER'].value = value

    # @property
    # def from_room(self, value):
        # TODO: from_room 

    @property
    def is_placed(self):
        """ ``bool`` for whether Room is Placed.
        Uses result of ``Room.Location`` attribute to define if room is Placed.
        """
        return bool(self._revit_object.Location)

    @property
    def is_bounded(self):
        """ ``bool`` for whether Room is Bounded.
        Uses result of ``Room.Area`` attribute to define if room is Bounded.
        """
        return self._revit_object.Area > 0

    def __repr__(self):
        return super(Room, self).__repr__(data={'name': self.name,
                                                'number': self.number})


class Area(Room):
    """
    `DB.Area` Wrapper
    Inherits from :any:`Room`

    >>> area = rpw.db.Area(SomeArea)
    <rpw:Area % DB.Area | name:USF area: 100.0>
    >>> area.name
    'Rentable'
    >>> area.is_placed
    True
    >>> area.is_bounded
    True

    Attribute:
        _revit_object (DB.Area): Wrapped ``DB.Area``
    """

    _revit_object_class = DB.Area
    _revit_object_category = DB.BuiltInCategory.OST_Areas
    _collector_params = {'of_category': _revit_object_category,
                         'is_not_type': True}

    @property
    def name(self):
        """ Area Scheme Name: Area attribute parameter"""
        return self.scheme.name

    @property
    def scheme(self):
        """ Area Scheme: Wrapped Area Scheme"""
        return AreaScheme(self._revit_object.AreaScheme)

    @property
    def area(self):
        """ Area: .Area attribute"""
        return self._revit_object.Area

    def __repr__(self):
        return super(Element, self).__repr__(data={'name': self.name,
                                                   'area': self.area})


class AreaScheme(Element):
    """
    `DB.AreaScheme` Wrapper
    Inherits from :any:`Element`

    >>> scheme = wrapped_room.scheme
    <rwp:AreaScheme % DB.AreaScheme | name:USF>
    >>> scheme.areas
    [ < Autodesk.Revit.DB.Area>, ...]
    >>> scheme.name
    'USF'

    Attribute:
        _revit_object (DB.AreaScheme): Wrapped ``DB.AreaScheme``
    """

    _revit_object_class = DB.AreaScheme
    _collector_params = {'of_class': _revit_object_class}

    @property
    def name(self):
        """ Area Scheme Name: Area attribute parameter"""
        return self._revit_object.Name

    @property
    def areas(self):
        """ Returns all Area Instances of this Area Scheme """
        bip = BipEnum.get_id('AREA_SCHEME_ID')
        param_filter = rpw.db.Collector.ParameterFilter(bip, equals=self._revit_object.Id)
        collector = rpw.db.Collector(parameter_filter=param_filter,
                                     **Area._collector_params)
        return collector.wrapped_elements

    def __repr__(self):
        return super(AreaScheme, self).__repr__(data={'name': self.name})