The GeometryStreamProps wire format describes how the graphics and appearance information for GeometricElement and GeometryPart is serialized to JSON. A GeometryStreamProps is an array of GeometryStreamEntryProps entries.
Appearance related entries are all completely optional. The recommended approach to establish graphical appearance is through SubCategoryAppearance. A GeometricElement's Category determines the default appearance for any graphics in its GeometryStream, which is the SubCategoryAppearance of the default SubCategory, see Category.myDefaultSubCategoryId. For a GeometryPart, it inherits the appearance established by the GeometricElement's GeometryStream through which it is instanced.
Some appearance entries override the default SubCategoryAppearance, while others are for supplying additional appearance information that is not generally applicable to all geometry types and isn't represented in SubCategoryAppearance. The following entries are specific to setting the appearance of graphics in the GeometryStream:
- The presence of a GeometryAppearanceProps entry in the GeometryStreamProps array always signifies clearing all SubCategoryAppearance overrides, even when all values are undefined.
- Defined values, with the exception of GeometryAppearanceProps.geometryClass, override a corresponding SubCategoryAppearance value.
- The SubCategoryAppearance used for geometry entries that follow in the GeometryStreamProps array is determined by GeometryAppearanceProps.subCategory. Default SubCategory for GeometricElement's Category is used when undefined.
- Modifies the default appearance from the LineStyle definition element identified by GeometryAppearanceProps.style or SubCategoryAppearance.styleId.
- Add instance specific overrides (ex. defining up direction for style in 3d) for stroked line styles. Override stroke lengths, gap lengths, and stroke widths.
- Stroked line styles are only applicable to IModelJson.CurvePrimitiveProps and IModelJson.CurveCollectionProps entries; it does not apply to edges of non-region surfaces or solids.
- Add a gradient, background, opaque, or outline fill to the display of IModelJson.PlanarRegionProps entries. Opaque fill can also be added to a IModelJson.IndexedMeshProps entry.
- Fill is only applicable to views that have ViewFlags.renderMode set to RenderMode.Wireframe.
- To be considered filled, AreaFillProps.display must be defined to something other than FillDisplay.Never.
- If AreaFillProps.display is defined as FillDisplay.ByView, the view's ViewFlags.fill determines whether the geometry displays as filled.
- Planar regions always display as surfaces in non-Wireframe views regardless of the value for FillDisplay; they will however use the fill color as opposed to the line color when fill is specified.
- Add a hatch, crosshatch, area pattern, or hatch definition to the display of IModelJson.PlanarRegionProps entries.
- A planar region can have both fill and pattern.
- Pattern display is controlled by ViewFlags.patterns for the view.
- Override for SubCategoryAppearance.materialId. Can be used to add or remove material for the display of surface and solid geometry.
- Material is only applicable to views that have ViewFlags.renderMode set to RenderMode.SmoothShade.
Geometry entries should always be inserted into the GeometryStreamProps array unrotated with a basis point of 0,0,0 (local coordinate frame). The world location and orientation of the geometry is determined by the GeometricElement's placement origin and angle(s), GeometricElement3dProps.placement and GeometricElement2dProps.placement.
A GeometricElement can be translated and rotated by just updating its placement, the geometry is not transformed.
The element aligned bounding box that is part of the placement is computed automatically based on the local coordinate geometry. An application should leave Placement3dProps.bbox and Placement2dProps.bbox undefined when inserting a new GeometricElement or updating an existing element's GeometryStream; any defined value will be ignored.
- Geometric primitive types: points, curves, paths, planar regions, bspline surfaces, surface primitives, solid primitives, linear sweeps of paths and regions, rotational sweeps of paths and regions, ruled sweeps of paths and regions, and index meshes.
- Add a reference to a GeometryPart from the GeometryStream of a GeometricElement. Used to instance repeated geometry; the part geometry is defined once and then shared by multiple GeometricElements or referenced multiple times by a single GeometricElement.
- The GeometryPartInstanceProps.origin and GeometryPartInstanceProps.rotation specify the relative location from the basis point (typically 0,0,0) used for the GeometricElement's geometry.
- Not valid when creating a GeometryPart, nesting of GeometryParts is not supported.
- As the GeometryPart does not specify a Category, and its GeometryStream does not support SubCategory changes; Category and SubCategory is established by the GeometricElement prior to adding a GeometryPartInstanceProps to the GeometryStreamProps array.
- Add a single line of text to the GeometryStream for a GeometricElement or GeometryPart.
- The TextStringProps.origin and TextStringProps.rotation specify the relative location from the basis point (typically 0,0,0) used for the GeometricElement's geometry.
- Raw BRep data, not generally useful outside of a geometry export scenario.
- The BRep data must be specifically requested using ElementLoadProps.wantBRepData.
- The body type, body to local transform, and any face material attachments are returned when requested using ElementLoadProps.wantGeometry.
- Store range of each geometric primitive to allow efficient filtering on range criteria without having to instantiate the geometry.
- Useful for GeometryStreams containing more than one geometric primitive; for a single geometric primitive, the geometry range is the placement's bounding box.
- Not necessary for GeometryPartInstanceProps entries, a GeometryPart stores its bounding box in GeometryPart.bbox.
- To include sub-ranges when creating a new GeometryStream, just add this entry to the GeometryStreamProps array before adding geometry. The low and high values will be computed automatically and will be ignored.
Creating a GeometryStream
To help with the creation of the GeometryStream for a new GeometricElement or GeometryPart, GeometryStreamBuilder is provided.
- Appearance information can be specified by a GeometryParams object that will append all relevant wire format entries to the GeometryStreamProps array.
- Geometric primitives can be specified by a GeometryQuery object that will append the appropriate wire format geometry entry.
- Supports supplying entries in world coordinates, such as from an InteractiveTool, and transforms them to placement relative local coordinate entries.
Iterating a GeometryStream
To help with inspecting the GeometryStream of an existing GeometricElement or GeometryPart, GeometryStreamIterator is provided.
- Appearance related wire format entries are accumulated in a single GeometryParams object.
- Iterator stops when it encounters a geometric entry: GeometryQuery, TextString, or a GeometryPart reference.
- Current iterator provides the GeometryParams that determines the appearance of the geometry entry as well as the GeometryStreamIteratorEntry.localToWorld transform.
- Supports returning entries in world coordinates when supplied the GeometricElement's placement.
- Supports iterating the GeometryStream of a GeometryPart in the context of a GeometricElement's GeometryStream.
Last Updated: 15 June, 2021