Elements From List 3D
Elements From List 3D is a utility tool module that provides two related commands for creating and visualizing 3D elements in Revit: placing family instances from CSV coordinate data, and creating filled regions from selected wall and caisson elements.
Overview
The tool module contains two ribbon commands:
| Command | Description | Availability |
|---|---|---|
| 3D Elements From List | Creates family instances at coordinates specified in a CSV file | Document open |
| Filled Regions From Elements | Creates filled regions from selected walls and caissons | Elements selected |
Source:
src/Tools/Common/3DElementsFromList/manifest.yml:6-24
Features
3D Elements From List Command
- CSV Import: Reads coordinate data from user-selected CSV files
- Flexible Column Ordering: Supports any column order with case-insensitive headers
- Optional ID Column: Maps CSV
idfield to element parameter - Auto-Family Loading: Automatically loads the required family if not present in project
- Multi-Format Support: Handles integers, decimals, negative values, and scientific notation
Source:
src/Tools/Common/3DElementsFromList/Features/ElementsFromList3DCommand.cs:13-72
Filled Regions From Elements Command
- Wall Support: Creates rectangular filled regions from wall bounding boxes
- Caisson Support: Creates circular filled regions from caisson diameter parameters
- Style Matching: Uses "solid gray" non-masking filled region type
- Invisible Lines: Applies invisible line style to region boundaries
- Automatic Comments: Sets "DB Tools" comment on created regions
Source:
src/Tools/Common/3DElementsFromList/Features/FilledRegionsFromElementsCommand.cs:12-62
Architecture
Module Structure
src/Tools/Common/3DElementsFromList/
+-- ElementsFromList3DToolModule.cs # Tool module registration
+-- DBTools.ElementsFromList3D.csproj # Project file
+-- manifest.yml # Tool manifest
+-- Features/
| +-- ElementsFromList3DCommand.cs # CSV import command
| +-- FilledRegionsFromElementsCommand.cs # Filled region command
| +-- CsvCoordinateParser.cs # Pure CSV parsing logic
| +-- CsvElementPlacer.cs # Element placement service
| +-- FilledRegionCreator.cs # Region creation service
+-- Assets/
| +-- 3d_elements_icon.png # Command icon
| +-- filled_regions_icon.png # Command icon
+-- Tests/
+-- CsvCoordinateParserTests.cs # Parser unit tests
+-- TEST_SUMMARY.md # Test documentation
Source: Directory structure of
src/Tools/Common/3DElementsFromList/
Data Flow
+------------------------+
| ElementsFromList3DCommand |
+-----------+------------+
|
(User selects CSV file)
|
v
+------------------------+
| CsvCoordinateParser |
| (Pure parsing logic) |
+-----------+------------+
|
(CoordinateRecords)
|
v
+------------------------+
| CsvElementPlacer |
| (Revit integration) |
+-----------+------------+
|
+-----------------+-----------------+
| |
v v
+------------------+ +-------------------+
| FamilyLoader | | Transaction |
| (Load/find family)| | (Create instances)|
+------------------+ +-------------------+
Separation of Concerns
The tool follows a clean separation pattern:
| Layer | Class | Responsibility |
|---|---|---|
| Command | ElementsFromList3DCommand |
Entry point, file selection, result display |
| Parsing | CsvCoordinateParser |
Pure CSV logic, no Revit/file dependencies |
| Placement | CsvElementPlacer |
Revit API integration, transaction management |
Source:
src/Tools/Common/3DElementsFromList/Features/CsvCoordinateParser.cs:59-63
Key Classes
Entry Points
| Class | File | Purpose |
|---|---|---|
ElementsFromList3DToolModule |
ElementsFromList3DToolModule.cs:5-7 |
Empty tool module; uses manifest-driven registration |
ElementsFromList3DCommand |
Features/ElementsFromList3DCommand.cs:17-72 |
CSV import command entry point |
FilledRegionsFromElementsCommand |
Features/FilledRegionsFromElementsCommand.cs:16-62 |
Filled region command entry point |
Source:
src/Tools/Common/3DElementsFromList/ElementsFromList3DToolModule.cs:5-7
Domain Types
| Type | File | Purpose |
|---|---|---|
CoordinateRecord |
Features/CsvCoordinateParser.cs:12-35 |
Immutable struct holding X, Y, Z, and optional ID |
CsvParseResult |
Features/CsvCoordinateParser.cs:40-57 |
Result type with success/failure semantics |
Source:
src/Tools/Common/3DElementsFromList/Features/CsvCoordinateParser.cs:12-35
Services
| Class | File | Purpose |
|---|---|---|
CsvCoordinateParser |
Features/CsvCoordinateParser.cs:63-153 |
Static parser with Parse(), ParseContent(), ParseFile() methods |
CsvElementPlacer |
Features/CsvElementPlacer.cs:18-162 |
Creates family instances from coordinate records |
FilledRegionCreator |
Features/FilledRegionCreator.cs:16-248 |
Creates filled regions from walls and caissons |
Source:
src/Tools/Common/3DElementsFromList/Features/CsvElementPlacer.cs:18
CSV Format
The CSV parser accepts files with the following format:
Required Columns
x- X coordinate (feet in Revit internal units)y- Y coordinate (feet in Revit internal units)z- Z coordinate (feet in Revit internal units)
Optional Columns
id- Identifier string (written to element's "ID" parameter if available)
Format Rules
| Feature | Behavior |
|---|---|
| Header case | Case-insensitive (X, x, X all valid) |
| Column order | Any order allowed |
| Extra columns | Ignored |
| Whitespace | Trimmed from headers and values |
| Empty rows | Skipped |
| Invalid rows | Skipped (row with unparseable numbers) |
| Number format | Integer, decimal, negative, scientific notation |
| Line endings | Windows (\r\n), Unix (\n), Mac (\r) |
Source:
src/Tools/Common/3DElementsFromList/Features/CsvCoordinateParser.cs:70-114
Example CSV
id,x,y,z
P001,100.5,200.25,10.0
P002,150.0,250.5,10.0
P003,200.75,300.0,10.0
Source:
src/Tools/Common/3DElementsFromList/Tests/CsvCoordinateParserTests.cs:453-471
Configuration
Manifest
id: DBTools.ElementsFromList3D
assembly: DBTools
moduleType: DBTools.ElementsFromList3D.ElementsFromList3DToolModule
order: 0
tool:
ribbonTools:
- internalName: DBTools.ElementsFromList3D
commandType: DBTools.ElementsFromList3D.ElementsFromList3DCommand
availabilityType: DBTools.App.Tools.Availability.DbtDocumentAvailability
runProfile: InlineUi
displayText: "3D Elements\nFrom List"
iconBaseKey: 3d_elements
tooltip: "Create 3D elements from a CSV file"
controlKind: PushButton
order: 10
- internalName: DBTools.FilledRegionsFromElements
commandType: DBTools.ElementsFromList3D.FilledRegionsFromElementsCommand
availabilityType: DBTools.App.Tools.Availability.DbtSelectionAvailability
runProfile: InlineUi
displayText: "Filled Regions\nFrom Elements"
iconBaseKey: filled_regions
tooltip: "Create filled regions from selected elements"
controlKind: PushButton
order: 11
Source:
src/Tools/Common/3DElementsFromList/manifest.yml:1-24
Availability Conditions
| Command | Availability Type | Condition |
|---|---|---|
| 3D Elements From List | DbtDocumentAvailability |
Any document open |
| Filled Regions From Elements | DbtSelectionAvailability |
Elements selected |
Source:
src/Tools/Common/3DElementsFromList/manifest.yml:9,18
Family Dependency
The 3D Elements command requires a specific family:
| Property | Value |
|---|---|
| File name | 3D-Elements-From-List.rfa |
| Family name | 3D-Elements-From-List |
| Category | Generic Model (OST_GenericModel) |
| Expected parameter | ID (string, for CSV ID mapping) |
Source:
src/Tools/Common/3DElementsFromList/Features/CsvElementPlacer.cs:24
The placer first searches for an existing family symbol in the document, then loads from the installed family library path if not found.
Source:
src/Tools/Common/3DElementsFromList/Features/CsvElementPlacer.cs:132
If the family file is missing from %APPDATA%/DBTools/Families, FamilyLoader attempts to self-heal by extracting an embedded copy of 3D-Elements-From-List.rfa into that folder before calling doc.LoadFamily(...).
Source:
src/DBTools.Core/Revit/Utilities/FamilyLoader.cs:55
Filled Region Requirements
The Filled Regions command requires specific project resources:
| Resource | Requirement |
|---|---|
| Filled Region Type | Name contains "solid" AND "gray", non-masking |
| Graphics Style | <Invisible lines> (exact name) |
| Caisson Family | Concrete-Caisson (family name, case-insensitive) |
| Caisson Diameter | Type parameter b (double) |
Source:
src/Tools/Common/3DElementsFromList/Features/FilledRegionCreator.cs:111-140
API Reference
CsvCoordinateParser
The static parser provides three entry points:
public static class CsvCoordinateParser
{
// Parse from string array (already split lines)
public static CsvParseResult Parse(IReadOnlyList<string> lines);
// Parse from content string (handles line splitting)
public static CsvParseResult ParseContent(string csvContent);
// Parse from file path (handles file I/O)
public static CsvParseResult ParseFile(string filePath);
}
Source:
src/Tools/Common/3DElementsFromList/Features/CsvCoordinateParser.cs:72,121,135
CoordinateRecord
Immutable value type for parsed coordinates:
public readonly struct CoordinateRecord : IEquatable<CoordinateRecord>
{
public double X { get; }
public double Y { get; }
public double Z { get; }
public string? Id { get; }
}
Source:
src/Tools/Common/3DElementsFromList/Features/CsvCoordinateParser.cs:12-25
CsvParseResult
Result type with explicit success/failure:
public sealed class CsvParseResult
{
public IReadOnlyList<CoordinateRecord> Records { get; }
public string? Error { get; }
public bool IsSuccess => Error == null;
public static CsvParseResult Success(IReadOnlyList<CoordinateRecord> records);
public static CsvParseResult Failure(string error);
}
Source:
src/Tools/Common/3DElementsFromList/Features/CsvCoordinateParser.cs:40-57
CsvElementPlacer
Creates elements within a transaction:
public sealed class CsvElementPlacer
{
public CsvElementPlacer(ITransactionRunner tx, Document doc, ILogger logger);
public (int CreatedCount, int FailedCount, string? ErrorMessage) Run(string csvPath);
}
Source:
src/Tools/Common/3DElementsFromList/Features/CsvElementPlacer.cs:27
FilledRegionCreator
Creates filled regions from selected elements:
public sealed class FilledRegionCreator
{
public FilledRegionCreator(ITransactionRunner tx, Document doc, View activeView, ILogger logger);
public (int CreatedCount, int SkippedCount) Run(ICollection<ElementId> selectedIds);
}
Source:
src/Tools/Common/3DElementsFromList/Features/FilledRegionCreator.cs:23-31
Testing
The tool includes comprehensive unit tests for the CSV parser:
Test Categories
| Category | Test Count | Description |
|---|---|---|
| Basic Success Cases | 5 | Valid CSV parsing scenarios |
| Column Order Variations | 4 | Different header orderings |
| Whitespace Handling | 4 | Trimming and empty row skipping |
| Number Formats | 6 | Integer, negative, scientific notation |
| Error Cases | 6 | Null, empty, missing columns |
| Invalid Data Handling | 3 | Malformed rows |
| ParseContent (String) | 5 | Line ending variations |
| CoordinateRecord | 5 | Equality and hash code |
| CsvParseResult | 2 | Success/failure factories |
| Integration Scenarios | 2 | Real-world CSV examples |
Total: 42 tests
Source:
src/Tools/Common/3DElementsFromList/Tests/TEST_SUMMARY.md:14-104
Running Tests
# Build test assemblies
bash build.sh BuildTests
# Run parser tests (headless, no Revit required)
dotnet test testing/DBTools.BuildArtifacts.Tests/DBTools.BuildArtifacts.Tests.csproj \
-c Release --filter "FullyQualifiedName~CsvCoordinateParser"
Source:
src/Tools/Common/3DElementsFromList/Tests/DBTools.ElementsFromList3D.Tests.csproj:19-20
User Workflow
Creating 3D Elements
- Click 3D Elements From List in the ribbon
- Select a CSV file with x, y, z columns
- Tool parses CSV and validates format
- Family is loaded if not present
- Elements are created at each coordinate
- Summary dialog shows created/failed counts (Warning variant when any rows fail)
Creating Filled Regions
- Select wall or caisson elements in the view
- Click Filled Regions From Elements in the ribbon
- Tool identifies element types (wall vs. caisson)
- For walls: creates rectangular regions from bounding box
- For caissons: creates circular regions from diameter
- Summary dialog shows created/skipped counts
Error Handling
The tool follows DBTools error handling conventions:
| Error Condition | Behavior |
|---|---|
| CSV file not found | Returns error message, no elements created |
| Missing x/y/z columns | Returns error message with column requirement |
| Invalid number format | Skips row, continues processing |
| One or more element creates fail | Continues processing, logs a warning summary, and shows a Warning summary dialog |
| Family not found | Attempts auto-load; fails with clear message if unavailable |
| No levels in document | Throws with descriptive message |
| No selection (regions) | Throws with user instruction |
| No suitable region type | Logs warning, returns with all skipped |
Source:
src/Tools/Common/3DElementsFromList/Features/CsvElementPlacer.cs:120
All commands display results via the alert service with appropriate variant (Info/Warning/Error).
Source:
src/Tools/Common/3DElementsFromList/Features/ElementsFromList3DHandler.cs:133
Related Documentation
- Architecture Overview - DBTools architecture and tool discovery
- Global Mapper - Example of a complex tool module
Source Files Reviewed
| File | Purpose |
|---|---|
manifest.yml |
Tool declaration and ribbon configuration |
ElementsFromList3DToolModule.cs |
Module registration |
ElementsFromList3DCommand.cs |
CSV import command |
FilledRegionsFromElementsCommand.cs |
Filled region command |
CsvCoordinateParser.cs |
Pure CSV parsing logic |
CsvElementPlacer.cs |
Element creation service |
FilledRegionCreator.cs |
Region creation service |
DBTools.ElementsFromList3D.csproj |
Project configuration |
CsvCoordinateParserTests.cs |
Unit tests |
TEST_SUMMARY.md |
Test documentation |