Exemple #1
0
        class AmbiguousUnion(properties.HasProperties):

            u = properties.Union(
                doc='ambiguous',
                props=[SomeProps, SameProps],
                strict_instances=True,
            )
Exemple #2
0
        class UnambigousUnion(properties.HasProperties):

            u = properties.Union(
                doc='unambiguous',
                props=[SomeProps, DifferentProps],
                strict_instances=True,
            )
Exemple #3
0
class SurfaceElement(ProjectElement):
    """Contains mesh, data, textures, and options of a surface"""
    geometry = properties.Union('Structure of the surface element',
                                props=(SurfaceGeometry, SurfaceGridGeometry))
    textures = properties.List(
        'Images mapped on the surface element',
        prop=ImageTexture,
        required=False,
        default=list,
    )
    subtype = properties.StringChoice('Category of Surface',
                                      choices=('surface', ),
                                      default='surface')

    def toVTK(self):
        """Convert the surface to a its appropriate VTK data object type."""
        from vtk.util import numpy_support as nps

        output = self.geometry.toVTK()

        # TODO: handle textures

        # Now add point data:
        for data in self.data:
            arr = data.array.array
            c = nps.numpy_to_vtk(num_array=arr)
            c.SetName(data.name)
            output.GetPointData().AddArray(c)

        return output
Exemple #4
0
 class HasOptionalUnion(properties.HasProperties):
     mybc = properties.Union(
         'union of bool or color',
         props=[properties.Bool(''),
                properties.Color('')],
         required=False,
     )
class Slide(_BaseCollaborationModel, spatial.base._BaseResource):
    """Slides provide a snapshot of a 3D scene

    They also provide a canvas for annotating the scene. By creating
    several slides, you can tell a story around your 3D data.
    """
    BASE_TYPE = 'slides'

    scene = spatial.base.InstanceSnapshot(
        'Current state of the 3D scene',
        instance_class=Scene,
    )
    annotation_plane = spatial.base.InstanceSnapshot(
        'Drawing plane for annotations perpendicular to line of sight',
        instance_class=DrawingPlane,
    )
    annotations = properties.List(
        'List of annotations on the scene',
        properties.Union(
            '',
            props=[
                spatial.base.InstanceSnapshot('', AnnotationText),
                spatial.base.InstanceSnapshot('', AnnotationInk),
            ],
        ),
        max_length=30,
        default=list,
    )
 class ManyProperties(properties.HasProperties):
     mystr = properties.String(
         'my string',
         serializer=reverse,
         deserializer=reverse,
     )
     myarr = properties.Array(
         'my array',
         serializer=to_string,
         deserializer=from_string,
     )
     myinst = properties.Instance(
         'my HP1',
         instance_class=HP1,
         serializer=serialize_a_only,
         deserializer=deserialize_from_a,
     )
     mylist = properties.List(
         'my list of HP1',
         prop=HP1,
         serializer=sum_of_a,
         deserializer=from_sum,
     )
     myunion = properties.Union(
         'string or HP1',
         props=(HP1, properties.String('')),
         serializer=just_the_classname,
         deserializer=reverse,
     )
class _BaseElementSurface(_BaseElement):
    """Base class for surface elements"""

    data = properties.List(
        'Data defined on the element',
        prop=properties.Union(
            '',
            props=[
                Pointer('', DataBasic),
                Pointer('', DataCategory),
                Pointer('', TextureProjection),
            ],
        ),
        max_length=100,
        default=list,
    )
    defaults = InstanceSnapshot(
        'Default visualization options',
        OptionsSurface,
        default={
            'visible': True,
            'color': {
                'value': 'random'
            },
            'opacity': {
                'value': 1.
            },
            'wireframe': {
                'active': False
            },
            'textures': [],
        },
    )
 class ManyProperties(properties.HasProperties):
     mystr = properties.String(
         'my string',
         required=False,
     )
     myarr = properties.Array(
         'my array',
         required=False,
     )
     myinst = properties.Instance(
         'my HP1',
         instance_class=HP1,
         required=False,
     )
     mylist = properties.List(
         'my list of HP1',
         prop=HP1,
         required=False,
         default=properties.utils.undefined
     )
     myunion = properties.Union(
         'string or HP1',
         props=(HP1, properties.String('')),
         required=False,
     )
class _BaseElementPointSet(_BaseElement):
    """Base class for point-set elements"""

    data = properties.List(
        'Data defined on the element',
        prop=properties.Union(
            '',
            props=[
                Pointer('', DataBasic),
                Pointer('', DataCategory),
                Pointer('', TextureProjection),
            ],
        ),
        max_length=100,
        default=list,
    )

    defaults = InstanceSnapshot(
        'Default visualization options',
        OptionsPoints,
        default={
            'visible': True,
            'color': {
                'value': 'random'
            },
            'opacity': {
                'value': 1.
            },
        },
    )
class _BaseOptionsData(_BaseOptionsItem):
    """Represents static or mapped data"""

    value = properties.Float(
        'Static value, used if data is unspecified',
        required=False,
    )

    data = properties.Union(
        'Data for attribute visualization',
        props=[
            Pointer('', DataBasic),
            Pointer('', DataCategory),
        ],
        required=False,
    )
    mapping = properties.Union(
        'Mapping to apply to data for visualization; must be specified '
        'if data is specified',
        props=[
            Pointer('', MappingContinuous),
            Pointer('', MappingDiscrete),
            Pointer('', MappingCategory),
        ],
        required=False,
    )

    @properties.validator
    def _validate_data(self):
        """Ensure value or data/mapping are set"""
        if self.data and not self.mapping:
            raise properties.ValidationError(
                message=(
                    'Mapping must be specified on visualization options if '
                    'data is present'),
                reason='missing',
                prop='mapping',
                instance=self,
            )
        if not self.data and self.value is None:
            raise properties.ValidationError(
                message=('Value must be specified on visualization options if '
                         'data is not'),
                reason='missing',
                prop='value',
                instance=self,
            )
def test_is_pointer():
    assert utils.is_pointer(PointerSubclass('', properties.HasProperties))
    assert utils.is_pointer(
        properties.Union('',
                         props=[
                             PointerSubclass('', properties.HasProperties),
                             properties.extras.Pointer(
                                 '', properties.HasProperties),
                         ]))
    assert not utils.is_pointer(
        properties.Instance('', properties.HasProperties))
    assert not utils.is_pointer(
        properties.Union('',
                         props=[
                             PointerSubclass('', properties.HasProperties),
                             properties.Instance('', properties.HasProperties),
                         ]))
Exemple #12
0
 class ValidateColorThenString(properties.HasProperties):
     values = properties.Union(
         'Values',
         props=[
             properties.List('', properties.Color('')),
             properties.List('', properties.String('')),
         ],
     )
Exemple #13
0
 class HasIntAndList(properties.HasProperties):
     myints = properties.Union('union of int or int list',
                               props=[
                                   properties.Integer(''),
                                   properties.List(
                                       '',
                                       properties.Integer(''),
                                       min_length=2)
                               ])
Exemple #14
0
 class HasOptPropsUnion(properties.HasProperties):
     mybc = properties.Union(
         'union of bool or color',
         props=[
             properties.Bool('', required=False),
             properties.Color('', required=False),
         ],
         required=True,
     )
class Plot(_BaseSceneComponent):
    """Object describing the contents of the 3D scene

    Contains info about how a plot is positioned in the scene, as well
    as the plot limits. Also contains active elements, slices, and
    measurements in the plot.
    """
    position = properties.Vector3(
        'x,y,z position of the plot center relative to scene origin',
        default=lambda: [0., 0, 0],
    )
    scale = properties.Vector3(
        'x,y,z scale of the plot coordinate system relative to scene '
        'coordinate system',
        default=lambda: [1., 1, 1],
    )
    rotation = properties.List(
        'Quaternion rotation of plot axes relative to scene axes',
        properties.Float(''),
        min_length=4,
        max_length=4,
        default=lambda: [0., 0, 0, 1],
    )
    lims = properties.List(
        'x,y,z limits, defined in plot coordinates',
        properties.Vector2(''),
        min_length=3,
        max_length=3,
        default=lambda: [[0, 0.00001]] * 3,
    )
    exaggeration = properties.List(
        'x,y,z exaggeration of the plot coordinates',
        properties.Integer('', min=1),
        default=lambda: [1, 1, 1],
    )
    slice_groups = properties.List(
        'Active slice groups; currently only one is supported',
        SliceGroup,
        max_length=1,
        default=lambda: [SliceGroup()],
    )
    measurements = properties.List(
        'List of active ruler instances; currently only one is supported',
        Ruler,
        max_length=1,
        default=list,
    )
    views = properties.List(
        'List of element views in the plot',
        properties.Union('', [
            view for key, view in _BaseSceneComponent._REGISTRY.items()
            if key[0] != '_' and issubclass(view, _BaseElementView)
        ]),
        max_length=100,
        default=list,
    )
Exemple #16
0
class Legend(ContentModel):
    """Legends to be used with DataMap indices"""
    values = properties.Union(
        'values for mapping indexed data',
        props=(
            ColorArray,
            DateTimeArray,
            StringArray,
            ScalarArray
        )
    )
Exemple #17
0
class SurfaceElement(ProjectElement):
    """Contains mesh, data, textures, and options of a surface"""
    geometry = properties.Union('Structure of the surface element',
                                props=(SurfaceGeometry, SurfaceGridGeometry))
    textures = properties.List(
        'Images mapped on the surface element',
        prop=ImageTexture,
        required=False,
        default=list,
    )
    subtype = properties.StringChoice('Category of Surface',
                                      choices=('surface', ),
                                      default='surface')
class _BaseElementLineSet(_BaseElement):
    """Base class for line-set elements"""

    defaults = properties.Union(
        'Default visualization options',
        props=[
            InstanceSnapshot('', OptionsLines),
            InstanceSnapshot('', OptionsTubes),
        ],
        default={
            'visible': True,
            'color': {
                'value': 'random'
            },
            'opacity': {
                'value': 1.
            },
        },
    )
class _BaseElementVolume(_BaseElement):
    """Base class for volume elements"""

    defaults = properties.Union(
        'Default visualization options',
        props=[
            InstanceSnapshot('', OptionsBlockModel),
            InstanceSnapshot('', OptionsVolumeSlices),
        ],
        default={
            'visible': True,
            'color': {
                'value': 'random'
            },
            'opacity': {
                'value': 1.
            },
            'wireframe': {
                'active': False
            },
        },
    )
Exemple #20
0
class ColorData(ProjectElementData):
    """Data array of RGB colors specified as three integers 0-255 or color

    If n x 3 integers is provided, these will simply be clipped to values
    between 0 and 255 inclusive; invalid colors will not error. This
    allows fast array validation rather than slow element-by-element list
    validation.

    Other color formats may be used (ie String or Hex colors). However,
    for large arrays, validation of these types will be slow.
    """
    array = properties.Union(
        'RGB color values at locations on a mesh (see location parameter)',
        props=(
            Int3Array,
            ColorArray
        )
    )

    @properties.validator('array')
    def _clip_colors(self, change):                                            #pylint: disable=no-self-use
        """This validation call fires immediately when array is set"""
        if isinstance(change['value'], Int3Array):
            change['value'].array = np.clip(change['value'].array, 0, 255)
class _BaseElement(_BaseResource):
    """Base class for elements"""

    BASE_TYPE = 'elements'

    data = properties.List(
        'Data defined on the element',
        prop=properties.Union(
            '',
            props=[
                Pointer('', DataBasic),
                Pointer('', DataCategory),
            ],
        ),
        max_length=100,
        default=list,
    )

    @property
    def num_nodes(self):
        """Number of nodes (vertices)"""
        raise NotImplementedError()

    @property
    def num_cells(self):
        """Number of cells"""
        raise NotImplementedError()

    @property
    def location_lengths(self):
        lengths = {
            'nodes': self.num_nodes,
            'cells': self.num_cells,
        }
        return lengths

    @properties.validator
    def _validate_data(self):
        """Check if element is built correctly"""
        if not self.data:
            return True
        for data in self.data:
            if isinstance(data, (string_types, TextureProjection)):
                continue
            if data.location not in self.location_lengths:
                raise properties.ValidationError(
                    message='Invalid location {} - valid values: {}'.format(
                        data.location, ', '.join(self.location_lengths)),
                    reason='invalid',
                    prop='data',
                    instance=self,
                )
            if isinstance(data.array, string_types):
                continue
            valid_length = self.location_lengths[data.location]
            if valid_length is None:
                continue
            if data.array.shape[0] != valid_length:
                raise properties.ValidationError(
                    message=('data {index} length {datalen} does not match '
                             '{loc} length {meshlen}'.format(
                                 index=data.name,
                                 datalen=data.array.shape[0],
                                 loc=data.location,
                                 meshlen=valid_length,
                             )),
                    reason='invalid',
                    prop='data',
                    instance=self,
                )
        return True
class DataBasic(_BaseData):
    """Basic numeric attribute data

    This data type is defined by an array that directly maps
    to an element geometry. For no-data values, use NaN.

    Currently, this only accepts 1D arrays and, when applied to a grid,
    the array must be stored in row-major order.
    """
    BASE_TYPE = 'data'
    SUB_TYPE = 'basic'

    array = Pointer(
        'Array of numeric values at locations on an element geometry, '
        'specified by the location property',
        Array,
    )
    location = properties.StringChoice(
        'Location of the data on geometry',
        choices={
            'nodes': ['N', 'node', 'vertices', 'corners'],
            'cells': ['CC', 'cell', 'segments', 'faces', 'blocks'],
        })
    mappings = properties.List(
        'Mappings associated with the data',
        prop=properties.Union(
            '',
            props=[
                Pointer('', MappingContinuous),
                Pointer('', MappingDiscrete),
            ],
        ),
        max_length=100,
        default=list,
    )

    @properties.validator('array')
    def _validate_array_1d(self, change):
        """Ensure the array is 1D"""
        if (isinstance(change['value'], string_types)
                or change['value'] is properties.undefined):
            return
        if not change['value'].is_1d():
            raise properties.ValidationError(
                message='{} must use 1D array'.format(
                    self.__class__.__name__, ),
                reason='invalid',
                prop='array',
                instance=self,
            )

    def to_omf(self, cell_location):
        self.validate()
        if self.location == 'nodes':
            location = 'vertices'
        else:
            location = cell_location
        omf_data = omf.ScalarData(
            name=self.name or '',
            description=self.description or '',
            location=location,
            array=self.array.array,
        )
        return omf_data
Exemple #23
0
class Surface(CompositeResource):
    """Contains all the information about a 2D surface"""
    mesh = properties.Union(doc='Mesh',
                            props=(properties.Instance('',
                                                       Mesh2D,
                                                       default=Mesh2D),
                                   properties.Instance('', Mesh2DGrid)))
    data = properties.List(
        doc='Data',
        prop=_SurfaceBinder,
        coerce=True,
        required=False,
        default=list,
    )
    textures = properties.List(
        doc='Textures',
        prop=Texture2DImage,
        coerce=True,
        required=False,
        default=list,
    )
    opts = properties.Instance(
        doc='Options',
        instance_class=_SurfaceOptions,
        default=_SurfaceOptions,
    )

    def _nbytes(self):
        return (self.mesh._nbytes() + sum(d.data._nbytes()
                                          for d in self.data) +
                sum(t._nbytes() for t in self.textures))

    @properties.validator
    def _validate_data(self):
        """Check if resource is built correctly"""
        for ii, dat in enumerate(self.data):
            assert dat.location in ('N', 'CC')
            valid_length = (self.mesh.nC
                            if dat.location == 'CC' else self.mesh.nN)
            if len(dat.data.array) != valid_length:
                raise ValueError(
                    'surface.data[{index}] length {datalen} does not match '
                    '{loc} length {meshlen}'.format(index=ii,
                                                    datalen=len(
                                                        dat.data.array),
                                                    loc=dat.location,
                                                    meshlen=valid_length))
        return True

    def _to_omf(self):
        import omf
        element = omf.SurfaceElement(
            name=self.title or '',
            description=self.description or '',
            geometry=self.mesh._to_omf(),
            color=self.opts.color or 'random',
            data=[],
            textures=[tex._to_omf() for tex in self.textures])
        for data in self.data:
            if data.location == 'CC':
                location = 'faces'
            else:
                location = 'vertices'
            omf_data = data.data._to_omf()
            omf_data.location = location
            element.data.append(omf_data)
        return element
Exemple #24
0
 class HasBoolColor(properties.HasProperties):
     mybc = properties.Union(
         'union of bool or color',
         props=[properties.Bool(''),
                properties.Color('')])
Exemple #25
0
    def test_union_default(self):
        class HasUnionA(properties.HasProperties):
            a = properties.Union(
                'union', (properties.Integer(''), properties.String('')))

        hu = HasUnionA()
        assert hu.a is None
        hu.a = 5
        hu.a = 'hi'
        del (hu.a)
        assert hu.a is None

        class HasUnionB(properties.HasProperties):
            b = properties.Union(
                'union',
                (properties.Integer('', default=5), properties.String('')))

        hu = HasUnionB()
        assert hu.b == 5
        hu.b = 'hi'
        del (hu.b)
        assert hu.b is None

        class HasUnionC(properties.HasProperties):
            c = properties.Union(
                'union',
                (properties.Integer(''), properties.String(
                    '', default='hi'), properties.Integer('')))

        hu = HasUnionC()
        assert hu.c == 'hi'
        hu.c = 5
        del (hu.c)
        assert hu.c is None

        class HasUnionD(properties.HasProperties):
            d = properties.Union(
                'union', (properties.Integer(''), properties.String(''),
                          properties.Integer('')),
                default=100)

        hu = HasUnionD()
        assert hu.d == 100
        hu.d = 5
        del (hu.d)
        assert hu.d is None

        with self.assertRaises(TypeError):
            properties.Union('union',
                             (properties.Integer(''), properties.Bool('')),
                             default=0.5)

        with warnings.catch_warnings(record=True) as w:
            properties.Union('union', (properties.Integer(
                '', default=5), properties.Bool('', default=True)))

            assert len(w) == 1
            assert issubclass(w[0].category, RuntimeWarning)

        with warnings.catch_warnings(record=True) as w:
            properties.Union('union', (properties.Integer(
                '', default=5), properties.Bool('', default=True)),
                             default=False)
            assert len(w) > 0
            assert issubclass(w[0].category, RuntimeWarning)

        def twelve():
            return 12

        HasUnionD._props['d'].default = twelve
        hu = HasUnionD()
        assert hu.d == 12
        HasUnionD._props['d'].default = properties.undefined
        hu = HasUnionD()
        assert hu.d is None
Exemple #26
0
 class HasUnionA(properties.HasProperties):
     a = properties.Union(
         'union', (properties.Integer(''), properties.String('')))
Exemple #27
0
 class HasProps1(properties.HasProperties):
     my_hp2 = properties.Instance('my HasProps2', HasProps2)
     my_union = properties.Union(
         'string or int',
         (properties.String(''), properties.Integer(''))
     )
Exemple #28
0
 class HasUnionC(properties.HasProperties):
     c = properties.Union(
         'union',
         (properties.Integer(''), properties.String(
             '', default='hi'), properties.Integer('')))
Exemple #29
0
 class HasUnionB(properties.HasProperties):
     b = properties.Union(
         'union',
         (properties.Integer('', default=5), properties.String('')))
Exemple #30
0
 class HasUnionD(properties.HasProperties):
     d = properties.Union(
         'union', (properties.Integer(''), properties.String(''),
                   properties.Integer('')),
         default=100)