Class: Feature

BIM. Feature

Defines are area on or in the surface of a building element.

A feature is a special type of BIM.Element that sits on or within the surface of another type of element. It is used to locate apertures such as windows and doors, as well as surface features such as switches, sensors, control panel, recessed lighting, air vents and even hung artwork.

The feature element defines the size and location relative to the surfaces of the wall, space, slab or plate to which it belongs.


new Feature( [config] [, typeName])

Creates a new feature on or within the surface of an element.

Parameters:
Name Type Argument Description
config object <optional>

An optional configuration object.

Properties of config:
Name Type Argument Description
name string <optional>

A human-readable name for this element.

uuid string <optional>

A universally unique identifier of this element.

visible boolean <optional>

Whether or not the entity is visible in the model.

extents THREE.Box3 <optional>

The bounding box of the element in model space.

openingType BIM.OPENING <optional>

The type of opening this feature represents.

typeComponent BIM.Component <optional>

The feature, window, door or panel type instance.

junction BIM.Junction <optional>

The junction to which this feature belongs.

alignment PD.ALIGN <optional>

Defines the alignment of the feature within its host surface, defaults to bottom-left corner.

offsetHor number <optional>

The horizontal distance from the aligned edge of the wall to the side of the feature.

offsetVer number <optional>

The vertical distance from the bottom/top of the wall to the bottom/top of the feature.

width number <optional>

The horizontal dimension of the feature opening area.

height number <optional>

The vertical dimension of the feature opening area.

open number <optional>

The fraction the feature is open, defaults to 1.

swapDirection boolean <optional>

Whether or not to flip the forward/backwards direction.

swapSides boolean <optional>

Whether or not to flip the inside/outside direction.

typeName string <optional>

An additional parameter typically used by subclasses to set the default feature name without modifying the config object.

Author:
  • drajmarsh

Extends

Members


:number

_openFraction

Stores the fraction that the feature is currently open.

The effect of this will vary between different feature types, and very probably in unimaginable ways by externally developed classes. Thus, it is included as a private property and exposed through a getter/setter which can be overridden.

Type
  • number

:PD.ALIGN

alignment

Defines the alignment of the feature within its host surface, defaults to bottom-left corner.

Type

:Map

attributes

Stores any arbitrary attributes associated with this entity.

This is a simple key/value map that can be used to store any additional information about the entity that may be required by the application such as reference ids, material types, fire ratings, costings, etc.

Type
  • Map
Inherited From:
Overrides:

:string

className <readonly>

The name of the subclass for this object instance.

This name must match the name of this class within the PD.Registry. Thus, the base implementation simply references this.constructor.getClassName() to ensure that this is always the case even for subclasses. As a result, there is rarely any need to override this method.

This property is used when copying, storing and exporting data for subclass instances to ensure that they are recreated as instances of the right class.

Type
  • string
Inherited From:
Overrides:

:string

displayName <readonly>

The name to display for this class within the user interface.

Type
  • string
Inherited From:
Overrides:

:BIM.ENTITY

entityType <readonly>

Defines the type of BIM entity this class represents.

This value is used by the PD.Registry for grouping elements and matching components. The base implementation simply references this.constructor.getEntityType() so that only a static method needs to be added to subclasses.

Type
Inherited From:
Overrides:

:THREE.Box3

extents

The 3D extents of the element as a bounding box.

Type
  • THREE.Box3
Inherited From:
Overrides:

:boolean

hasChanged

Whether or not the entity has recently changed and needs to update.

This property is typically set by the user interface or other parts of the framework when the entity's properties have changed and any visual representations need to be updated.

Type
  • boolean
Inherited From:
Overrides:

:number

height

The vertical size of the feature, in model units.

Type
  • number

:string

iconName <readonly>

The name of the SVG icon to associate with this object instance.

This name should match the name of the icon associated with this class within the PD.Registry. Thus, the default implementation simply references this.constructor.getClassName() to ensure that this is always the case, even for subclasses. However, you can override this property if you want a different icon dependant on other properties of the class instance, as shown in the example below.

Type
  • string
Inherited From:
Overrides:
Example
// Overriding the icon name.

MyElements.Table = class extends PD.Base {
    /// ...
    get iconName() {
        if (this.hasRoundTop) return 'MyElements.Table.Round';
        return this.constructor.getClassName();
    };
    /// ...
 };

:number

id

A unique integer identifier for fast discovery and/or equality checking.

This identifier is unique within the current project data and is primarily intended to facilitate fast lookup and equality checking. It is assigned automatically when the feature is created and should not change. It is much simpler than the uuid property, being a numeric integer rather than a long string of characters, and is the preferred way of comparing feature entities to see if they are the same.

Type
  • number

:boolean

isCurved

Whether or not the feature sits in a curved wall.

Type
  • boolean

:boolean

isEntity <readonly>

A flag identifying this object as an entity.

Type
  • boolean
Inherited From:
Overrides:

:boolean

isExternal

Whether or not the feature is on an external face of the building.

Type
  • boolean

:boolean

isFeature <readonly>

A flag identifying this object as a feature.

Type
  • boolean

:boolean

isOpen <readonly>

Whether or not the feature is more open than closed.

Type
  • boolean

:boolean

isOperable <readonly>

A flag indicating whether this entity responds to different values of BIM.Feature#openFraction.

Type
  • boolean

:BIM.Junction

junction

The junction to which this feature belongs.

The value of this property is automatically set whenever the feature is updated and when assigned to junction.

Type

:number

maxHeight

The maximum height of the feature in its junction, in model units.

Type
  • number

:number

maxWidth

The maximum width of the feature in its junction, in model units.

Type
  • number

:string

name

A human-readable name for this item instance.

Type
  • string
Inherited From:
Overrides:

:number

offsetHor

The horizontal distance of the anchor point from the aligned edge of the host surface.

The meaning of this value depends on the current alignment property value. For LEFT and RIGHT alignments, it is the distance of the feature from the respective vertical edge of the host surface. For CENTER alignments, it is the minimum allowable offset from both LEFT and RIGHT edges.

Type
  • number

:number

offsetVer

The vertical distance of the anchor point from the aligned edge of the host surface.

The meaning of this value depends on the current alignment property value. For TOP and BOTTOM alignments, it is the distance of the feature from the respective horizontal edge of the host surface. For MIDDLE alignments, it is the minimum allowable offset from both TOP and BOTTOM edges.

Type
  • number

:number

openFraction

Defines the fraction of the feature that is open.

This value will affect different feature types in different ways, and very likely in some completely unexpected ways with externally developed feature types. It is a value that ranges from 0 to 1 for most kinds of feature, and -1 to 1 for some doors that can open two ways.

Type
  • number

:THREE.Vector2

pos

The actual position of the feature relative to its host surface.

This gives the final calculated relative position of the feature. These may be different to preferred offsetHor and offsetVer values as the feature may need to be modified if its size would extend beyond the extents of the surface it belongs to. Preference is always given to maintaining the size and shape of the feature, with its position adjusted first to make it fit.

Type
  • THREE.Vector2

:boolean

selected

Whether or not the entity is in the current selection set.

This property is typically set by the user interface when the user selects or deselects entities within the model view. The PD.SelectionManager uses this property to keep track of which entities are currently selected.

Type
  • boolean
Inherited From:
Overrides:

:THREE.Shape|null

shape

An optional 2D shape from which to generate the profile.

The bottom-left corner of this shape, or the minimum extents of its bounding box, should ideally start at the origin in order to be positioned accurately within the feature's host surface(s).

Type
  • THREE.Shape | null

:PD.Shell

shell

Stores the jamb surfaces of the feature as well as any frame geometry.

Type

:THREE.Vector2

size

The size of the feature within the plane of its host surface.

This gives the final calculated size of the feature. This may be different from the preferred width and height values as the feature may need to be modified if its size would extend beyond the extents of the surface it belongs to. Preference is always given to maintaining the size and shape of the feature and adjusting its position first to make it fit. However, if the host surface is smaller than the preferred size, the actual size will be then reduced to fit.

Type
  • THREE.Vector2

:boolean

swapDirection

Whether or not to flip the forward/backwards direction.

Type
  • boolean

:boolean

swapSides

Whether or not to flip the inside/outside direction.

Type
  • boolean

:BIM.Component|null

typeComponent

A type component reference.

The assigned BIM.Windows, BIM.Doors or BIM.Panel type component provides the feature with all its geometric characteristics. Without an assigned feature type, the feature is rendered as a simple void through an element.

Type

:string

typeDisplayName <readonly>

Retrieves the display name of the assigned type component.

Type
  • string

:string

uuid

A universally unique identifier for the item instance.

Type
  • string
Inherited From:
Overrides:

:boolean

visible

Whether or not the entity is visible within the model.

The framework tries its best to avoid rendering invisible entities, but depending on the type of entity and how it is represented, this may not always be possible. For example, not rendering a chair is

Type
  • boolean
Inherited From:
Overrides:

:number

width

The horizontal size of the feature, in model units.

Type
  • number

:object

icon <static>

The icon associated with this class in the PD.Registry.

See PD.Base.icon for more information on this object format.

Type
  • object

Methods


addProfileToPolyMesh(mesh, side)

Adds an outline of the given feature profile to the mesh.

Parameters:
Name Type Description
mesh PD.PolyMesh

The mesh to add the profile outline to.

side PD.SIDE | Array

Either the side of the profile, or the profile itself as an array of points.

Returns:

Returns this feature to support method chaining.

Type
BIM.Feature

alignCursor(cursor)

Rotates the cursor to align with this feature.

Parameters:
Name Type Description
cursor PD.Cursor

The cursor to align.

Returns:

Returns true if cursor is valid and was aligned.

Type
boolean

checkDynamicParameter(param, group)

Checks the dynamic parameter value and rebuilds the element if required.

See the PD.Base#checkDynamicParameters method for more details.

Parameters:
Name Type Description
param PD.Parameter

The dynamic parameter that changed.

group PD.ParamGroup

The group that the dynamic parameter belongs to.

Inherited From:
Overrides:
Example
checkDynamicParameter(param, group, host) {

     switch (param.name) {

         case 'height':
             if (param.value < 1.0) param.value = 1.0;
             break;

         case 'width':
         case 'length':
             if (param.value < 100.0) param.value = 100.0;
             if (this.standardBedSize > 0) { // If not custom.
                 group.setParameterValue('standardBedSize', 0);
                 this.standardBedSize = 0; // Make it custom.
             }
             break;

         case 'standardBedSize': {
                 const std_bed = this.getStandardBedSize(Math.round(param.value));
                 if (std_bed != null) {
                     const [ width, length ] = (PD.DIMENSION.useImperial) ? std_bed.sizeImperial : std_bed.sizeMetric;
                     this.width = PD.Utils.toNumber(width, this.width);
                     group.setParameterValue('width', this.width);
                     this.length = PD.Utils.toNumber(length, this.length);
                     group.setParameterValue('length', this.length);
                 }
             } break;

       }

 };

clone()

Creates a copy of this instance with different name and uuid.

Inherited From:
Overrides:
Returns:

Returns a new instance with copied values.

Type
PD.Base | null

computeSharedLocalCoordinates()

Sets up a shared local coordinate set for the given feature.

As this returns shared local coordinates, you must assume that these computed settings are only valid when used within the method or function that called this method, or within any methods directly invoked by the calling method/function. If you try to update another feature after calling this method, or use promises or await where that might happen, then there is a very real risk that something else may change them in the interim.

This method assumes that the update() method has already been called on the given feature after any changes to it so that its core profile has already been computed.

The origin of the local coordinates is set to the bottom-left corner of the feature opening profile. The U-axis is set to the direction of travel from the given junction to the next, and the V-axis to the normal to that direction. The W-axis is set to the normal of the path that the junction belongs to or, if it doesn't belong to a path, its own upVector.

Returns:

Returns the updated local coordinates.

Type
PD.LocalCoordinates

deleteAttribute(name)

Removes an attribute from this entity.

Parameters:
Name Type Description
name string

The name of the attribute to remove.

Inherited From:
Overrides:
Returns:

Returns this entity to support method chaining.

Type
PD.Base

dimension(mesh, size)

Adds dimension lines around a feature when selected.

Parameters:
Name Type Description
mesh PD.PolyMesh

The mesh to render to.

size number

The size of dimension in model units.

Returns:

Returns true if anything was added to the mesh.

Type
boolean

findByRay(selection)

Checks if the given ray intersects the feature.

Parameters:
Name Type Description
selection PD.Selection

The interactive selection accumulator.

Returns:

Returns the facet that was intersected, or null.

Type
PD.Polygon | null

fromJSON(data)

Safely copy properties from a source object.

See the PD.Base#fromJSON method for more details.

Parameters:
Name Type Description
data object

The source object containing data to copy.

Overrides:
Returns:

Returns this instance to support method chaining.

Type
BIM.Feature

getAlignmentReferencePos(point)

Sets the given point to the alignment reference point in the feature.

Parameters:
Name Type Description
point THREE.Vector3

The point to set the position of.

Returns:

Returns the given point to support method chaining.

Type
THREE.Vector3

getAttribute(name)

Retrieve an attribute stored on this entity, if it exists.

Parameters:
Name Type Description
name string

The name of the attribute to retrieve.

Inherited From:
Overrides:
Returns:

Returns the attribute value, or undefined if it does not exist.

Type
any | undefined

getDynamicParameters( [no_title])

Provides a list of dynamic parameter groups for this feature.

See the PD.Base#getDynamicParameters method for more details.

Parameters:
Name Type Argument Description
no_title boolean <optional>

If true, the group is displayed without a section title.

Inherited From:
Overrides:
Returns:

Returns an array of PD.ParamGroup objects.

Type
Array
Example
getDynamicParameters(host) {
     return [
         new PD.ParamGroup({
             name: 'mainParams',
             title: 'Table Parameters',
             target: this,
             params: [
                 new PD.Parameter({ name: 'height', title: 'Table Height', value: this.height, paramType: PD.ParamType.SmallDistance, description: 'The height from floor level to the top of the table.' }),
                 new PD.Parameter({ name: 'size', title: 'Table Top Size/Diameter', value: this.size, paramType: PD.ParamType.Distance, description: 'The size of the table top when not defined by a closed path.' }),
                 new PD.Parameter({ name: 'thickness', title: 'Table Top Thickness', value: this.thickness, paramType: PD.ParamType.SmallDistance, description: 'The thickness of the table top surface.' }),
                 new PD.Parameter({ name: 'offset', title: 'Offset From Path', value: this.offset, paramType: PD.ParamType.SmallDistance, description: 'The offset distance from the table path.' }),
                 new PD.Parameter({ name: 'swapSides', title: 'Swap Sides', value: this.swapSides, paramType: PD.ParamType.Boolean, description: 'Reverse the direction of the table relative to its path.' }),
                 new PD.Parameter({ name: 'isRound', title: 'Round Table', value: this.isRound, paramType: PD.ParamType.Boolean, description: 'Whether or not the table surface is round.'  }),
             ]
         }),
         new PD.ParamGroup({
             name: 'legParams',
             title: 'Leg Parameters',
             target: this,
             params: [
                 new PD.Parameter({ name: 'legCount', title: 'Number of Legs', value: this.legCount, paramType: PD.ParamType.Integer, description: 'The number of legs on the table.' }),
                 new PD.Parameter({ name: 'legSize', title: 'Leg Size', value: this.legSize, paramType: PD.ParamType.SmallDistance, description: 'The thickness of each leg of the table.' }),
                 new PD.Parameter({ name: 'legInset', title: 'Leg Edge Inset', value: this.legInset, paramType: PD.ParamType.SmallDistance, description: 'The inset distance of each leg from the table edge.' }),
                 new PD.Parameter({ name: 'legOffset', title: 'Leg Edge Offset', value: this.legOffset, paramType: PD.ParamType.Fraction, description: 'The relative distance of the leg along each edge span.' }),
                 new PD.Parameter({ name: 'legSpan', title: 'Max. Distance Between Legs', value: this.legSpan, paramType: PD.ParamType.Distance, description: 'The maximum distance between legs along each edge span.' })
             ]
         })
     ];
 };

getRefHeight()

Retrieve the last stored reference height in model units.

This value is set by calling the storeRefData() method.

Returns:

Returns the reference height.

Type
number

getRefOffsetX()

Retrieve the last stored reference X offset in model units.

This value is set by calling the storeRefData() method.

Returns:

Returns the reference X offset.

Type
number

getRefOffsetY()

Retrieve the last stored reference Y offset in model units.

This value is set by calling the storeRefData() method.

Returns:

Returns the reference Y offset.

Type
number

getRefWidth()

Retrieve the last stored reference width in model units.

This value is set by calling the storeRefData() method.

Returns:

Returns the reference width.

Type
number

getReferenceDepth()

Retrieves the depth of the host surface material.

Returns:

Returns the host surface material depth, in model units.

Type
number

getTypeComponentParameters()

Provides a list of component parameter groups for this element.

See the PD.Base#getDynamicParameters method for more details.

Returns:

Returns an array of PD.ParamGroup objects.

Type
Array

intersectExtents(ray, intersection)

Determines if the given ray intersects the entity extents.

Parameters:
Name Type Description
ray THREE.Ray

The ray to find the intersection for.

intersection THREE.Vector3

The vector to store the intersection point, if any.

Inherited From:
Overrides:
Returns:

Returns the intersection point, or null if no intersection.

Type
THREE.Vector3 | null

intersectLightRay(ray, result)

Handles the intersection of a light or shading ray with this feature.

This method typically intersects the ray with its BIM.Feature#glazingPanes, if it has any, and then with its BIM.Feature#shell. Override this method in your custom feature if it needs to handle light ray intersections differently.

Parameters:
Name Type Description
ray THREE.Ray

The ray defining the origin and direction of the light ray.

result object

An object containing information about the light ray.

Properties of result:
Name Type Description
intersection THREE.Vector3

Stores the triangle intersection point as a {x,y,z} vector.

transmittance number

Stores the accumulated transmittance of all intersected surfaces.

reflectance number

Stores the accumulated reflectance from all intersected surfaces.

color number

Stores the color of the primary intersected surface.

Returns:

Returns true if the light ray hit an opaque surface and updated results.

Type
boolean

moveAlignmentReferencePos(point)

Constrains the feature to be within host junction.

Parameters:
Name Type Description
point THREE.Vector3

The point to constrain inside the junction.

Returns:

Returns true if the point was constrained.

Type
boolean

rebuild(level, view)

Displays the frame of the feature as 3D geometry.

NOTE: This method also generates the actual geometry of the jambs and frames. This has to be done during the level rebuild process as only then can we be sure that all of the extruded external wall geometry has been created. It also ensures that the feature geometry matches the 'as-rendered' condition so that interactive selection is accurate by default.

Parameters:
Name Type Description
level BIM.Level

The level currently being rebuilt.

view PD.ViewData

The view definition to render the model within.

Returns:

Returns this feature to support method chaining.

Type
BIM.Feature

renderToSVG(width, height, planView)

Constructs a plan or elevation view of this aperture as SVG elements.

Plan-Section View
   ---+ - - - - - - - - - - - - - - - - - - - - - +---
      |                                           |
      +---+-----------------------------------+---+
      |   |                                   |   |
      +---+-----------------------------------+---+
      |                                           |
   ---+ - - - - - - - - - - - - - - - - - - - - - +---
Elevation View
      +-------------------------------------------+
      |                                           |
      |   +-----------------------------------+   |
      |   |                                   |   |
      |   |                                   |   |
      |   |                                   |   |
      |   |                                   |   |
      |   |                                   |   |
      |   |                                   |   |
      |   +-----------------------------------+   |
      |                                           |
      +-------------------------------------------+
Parameters:
Name Type Default Description
width number

The width of the available SVG viewBox.

height number

The height of the available SVG viewBox.

planView boolean true

Whether to render in plan view instead of elevation, defaults to true.

Returns:

Returns a vector image of this aperture as SVG elements.

Type
string

selectByFrustum(selection)

Checks if feature is inside frustum and updates the selection.

Parameters:
Name Type Description
selection PD.Selection

The interactive selection accumulator.

Returns:

Returns true if the feature was selected and the selection updated, otherwise false.

Type
boolean

setAttribute(name, value)

Stores an attribute on this entity, or replaces it's existing value.

Parameters:
Name Type Description
name string

The name of the attribute to store.

value string

The attribute value to store.

Inherited From:
Overrides:
Returns:

Returns this entity to support method chaining.

Type
PD.Base

setExtents(bbox)

Set the 3D extents of the element as a bounding box.

Override this method in bounding box driven building elements such as equipment, imported or parametric meshes to rescale or regenerate their underlying geometry whenever it changes.

Parameters:
Name Type Description
bbox THREE.Box3

The new bounding box extents to set.

Inherited From:
Overrides:
Returns:

Returns this entity to support method chaining.

Type
PD.Base

storeRefData()

Snapshots the position and size of a feature ready for a move.

Returns:

Returns this feature to support method chaining.

Type
BIM.Path

update(junction [, segments])

Updates the profile and shell of the feature relative to the junction.

Parameters:
Name Type Argument Description
junction BIM.Junction

The junction that owns the feature.

segments number <optional>

The number of segments to divide shape curves.

Returns:

Returns this feature to support method chaining.

Type
BIM.Feature

updateDynamicParameters(param, group)

Checks the dynamic parameter value and rebuilds the component if required.

See the PD.Base#updateDynamicParameters method for more details.

Parameters:
Name Type Description
param PD.Parameter

The dynamic parameter that changed.

group PD.ParamGroup

The group that the dynamic parameter belongs to.

Inherited From:
Overrides:
Returns:

Returns true if the component was rebuilt and a model update is required.

Type
boolean
Examples
updateDynamicParameters(param, group) {

     /// When you want parent class to use its logic.
     if (super.updateDynamicParameters(param, group)) {
         if (param.name == 'i_am_special') this.doSomethingSpecial();
         return true;
     }

     return false;

 };
updateDynamicParameters(param, group) {

     /// When you don't want parent to handle parameter updates.
     if (PD.Base.updateDynamicParametersOnHost(param, group, this)) {

         /// Invalidate geometry.
         if (this.typeComponent) {
             ++this.typeComponent.updateIndex;
         }

         /// Rebuild element.
         this.hasChanged = true;
         this.update();

         /// Only update site mesh.
         if (this.onlyUsesSiteMesh) {
             const level = this.level;
             if (level) { // Don't trigger whole level update.
                 level.rebuildSiteMesh();
                 PD.GlobalActions.redrawAndUpdateSelection();
                 return false;
             }
         }

         return true;

     }

     return false;

 };
updateDynamicParameters(param, group) {

     /// The following three lines of code replicate
     /// `PD.Base.updateDynamicParametersOnHost()`, which you can
     /// use if you need to access `target` without having to call
     /// `group.getTarget() || this` twice.

     const target = group.getTarget() || this;
     target.checkDynamicParameter(param, group, this);
     if (param.setValueOnHostIfDifferent(target, group, this)) {

         /// You can now use `target`.
         if (target.myOwnMeshThatIsUpdatedDuringRebuild) {

             /// Rebuild element.
             this.hasChanged = true;
             this.update();

             /// If no level meshes or other elements are affected,
             /// simply update the target locally and return false.
             this.myOwnMeshThatIsUpdatedDuringRebuild.update();

             /// Update selection meshes if the
             /// element's highlight geometry changed.
             PD.GlobalActions.updateSelectionMeshes();
             return false;

         }

         return true;

     }

     return false;

 };

getClassDescription() <static>

A brief description of this class to accompany its icon.

Returns:

Returns a brief description.

Type
string

getClassName() <static>

The name of this class within the PD.Registry.

See PD.Base.getClassName for more details as this is required for use with the PD.Registry.

Returns:

Returns the registered name of this class.

Type
string

getDisplayName() <static>

The name to display within the user interface.

Returns:

Returns the display name.

Type
string

getEntityType() <static>

Defines the type of BIM entity this class represents.

See BIM.Entity.getEntityType for more details as this is required for use with the PD.Registry.

Returns:

Returns the BIM entity type this class represents.

Type
BIM.ENTITY