Table of Contents

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 id field 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

  1. Click 3D Elements From List in the ribbon
  2. Select a CSV file with x, y, z columns
  3. Tool parses CSV and validates format
  4. Family is loaded if not present
  5. Elements are created at each coordinate
  6. Summary dialog shows created/failed counts (Warning variant when any rows fail)

Creating Filled Regions

  1. Select wall or caisson elements in the view
  2. Click Filled Regions From Elements in the ribbon
  3. Tool identifies element types (wall vs. caisson)
  4. For walls: creates rectangular regions from bounding box
  5. For caissons: creates circular regions from diameter
  6. 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

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