Brick

This class is a child of PrimitiveShape.

Contents

classdef Brick < PrimitiveShape
    %This Class defines the Brick object. This is a subclass of Primitive
    %Shape and defines the geometric properties for a brick.
    %
    %   URL : $URL: $
    %   Log : $Id: Brick.html,v 1.1 2008/07/23 12:51:18 jberg Exp $
    %   Copyright (c) 2008 The MathWorks, Inc.

Class Properties

    properties ( SetAccess = 'public', GetAccess = 'public' )
        width = 1;                          % (pos def double) x-axis
        height = 1;                         % (pos def double) y-axis
        depth = 1;                          % (pos def double) z-axis
    end
    properties ( Dependent = true )
        moment_of_inertia_about_CG;     % (3x3 double)
        volume;                         % (pos def double)
    end
    properties ( SetAccess = 'private', GetAccess = 'public', Constant = true )
        % The order of dimension_order needs to be the same as that
        % expected by org.j3d.geom.BoxGenerator.setDimensions()
        %	setDimensions(float width, float height, float depth)
        dimension_order = {'width','height','depth'};
    end
    properties ( SetAccess = 'private', GetAccess = 'private', Constant = true )
        PROPERTY_LIST = {
            'coord_system'  % From parent class Shape
            'depth'         %
            'height'        %
            'material'      % From parent class PrimitiveShape
            'name'          % From parent class Shape
            'orientation'   % From parent class Shape
            'origin'        % From parent class Shape
            'width'         %
            };
    end

    methods

Constructor

        function obj = Brick(varargin)
            if(mod(nargin,2)~=0)
                error('Expecting inputs as property name-value pairs.')
            end

            prop_list = eval([mfilename '.PROPERTY_LIST']);
            n_props = length(prop_list);
            error(nargchk(0, 2*n_props, nargin,'string'));

            % Check to see if any input arguments are CoordSystem objects.  If
            % so, then this object is being created from another similar object
            % and there is no need to create the Origin and/or CG CoordSystems.
            if ~nargin || ~strmatch('coord_system',varargin(1:2:end),'exact')
                obj.add_coord_system; % Add Origin CS
            end

            % Child-specific default
            obj.name = 'New Brick';

            % Property Name-Value pair matching
            for ii=1:2:nargin
                prop    = varargin{ii};
                val     = varargin{ii+1};
                idx     = strmatch(lower(prop),lower(prop_list),'exact');
                if isempty(idx)
                    error('%s: This property is unknown',...
                        'or cannot be set during the construction',...
                        'of the object: %s ',prop,mfilename);
                else
                    obj.(prop_list{idx}) = val;
                end
            end
            % Create default CoordSystems specific to this Primitive. These are
            % not editable and are wrt the Origin of this Shape.
            % CG
            if obj.n_coord_system < 2
                csTmp = CoordSystem('name','CG',...
                    'is_deletable',false,...
                    'is_fixed',true,...
                    'origin',[0 0 0],...
                    'parent_shape',obj);
                csTmp.reference_CS = obj.coord_system{1};
                obj.add_coord_system(csTmp);
            end
			obj.attach_primitive();
        end

SET Methods

        function set.depth(obj, in)
            prop_name = 'depth';
            prop_type = 'double';
            [valid_flag in] = Validate.SCALAR(in,'type',prop_type,'minVal',eps);
            if valid_flag
                obj.(prop_name) = in;
            end
        end
        function set.height(obj, in)
            prop_name = 'height';
            prop_type = 'double';
            [valid_flag in] = Validate.SCALAR(in,'type',prop_type,'minVal',eps);
            if valid_flag
                obj.(prop_name) = in;
            end
        end
        function set.width(obj, in)
            prop_name = 'width';
            prop_type = 'double';
            [valid_flag in] = Validate.SCALAR(in,'type',prop_type,'minVal',eps);
            if valid_flag
                obj.(prop_name) = in;
            end
        end

GET Methods

        function vol = get.volume(obj)
            vol = obj.width * obj.height * obj.depth;
        end
        function inertia_tensor = get.moment_of_inertia_about_CG(obj)
            % this inertia is calculated about the center of mass of this shape
            m = obj.mass;
            w = obj.width;
            h = obj.height;
            d = obj.depth;
            inertia_tensor = (m/12).*[(h^2+d^2) 0 0; 0 (w^2+d^2) 0; 0 0 (w^2+h^2)];
        end
    end
	methods ( Access = 'public')

Public HELPER Methods

        function attach_primitive(obj)
            x = obj.width;
            y = obj.height;
            z = obj.depth;

            the_appearance = obj.material.appearance;
            p = org.j3d.renderer.java3d.geom.Box(x, y, z, the_appearance);
            p.setName(mfilename);

            % Store primitive for future modifications as necessary.
            obj.primitive = p;

            obj.attach_primitive_common(p);
            % Used to be obj.attach_primitive@PrimitiveShape(...), but resulted
            % in top down calling sequence, which we don't want.
        end
        function attach_generator(obj)
        end
    end

    methods ( Access = 'private' )

Private HELPER Methods

        function update_shape_appearance(obj)
            % This is called whenever a Shape's material type has changed
            a_primitive = obj.primitive;
            if ~isempty(a_primitive)
                if true % Using org.j3d.renderer.java3d.geom.* for primitives
                    a_primitive.setAppearance(obj.material.appearance);
                else    % Using com.sun.j3d.utils.geometry.* for primitives
                    ii = 0;
                    while true
                        a_shape3D = a_primitive.getShape(ii);
                        if isempty(a_shape3D)
                            break;
                        else
                            a_shape3D.setAppearance(obj.material.appearance);
                            % a_shape3D.getAppearance.setMaterial(obj.material)
                            ii = ii+1;
                        end
                    end
                end
            end
        end
    end


    methods ( Static = true )

LOADOBJ Method

        function B = loadobj(A)
            % We use loadobj so that when a stored object is loaded, we can
            % perform necessary steps that are contained in the constructor. We
            % have to do this because the constructor is not executed when an
            % object is loaded.
            Log.msg(sprintf('\n%s::%s',mfilename,'loadobj (Entering)'));
            prop_list = eval([mfilename '.PROPERTY_LIST']);

            % Construct object using the stored properties
            storedFields = fieldnames(A);
            args = cell(0);
            for ii=1:length(storedFields)
                prop = storedFields{ii};
                idx     = strmatch(lower(prop),lower(prop_list),'exact');
                if ~isempty(idx)
                    args{end+1} = prop; %#ok<AGROW>
                    args{end+1} = A.(storedFields{ii}); %#ok<AGROW>
                end
            end
            B = Brick(args{:});
            Log.msg(sprintf('%s::%s',mfilename,'loadobj (Exiting)'));
        end
    end
end