Skip to main content

Overview

The Sweep class creates 3D shapes by sweeping a 2D profile along a 3D path. This powerful technique enables creation of pipes, tubes, rails, and complex extruded forms that follow custom trajectories.

Constructor

const sweep = new Sweep(options?: ISweepOptions);

ISweepOptions

ogid
string
Unique identifier for the sweep. Auto-generated if not provided.
path
Vector3[]
required
Array of points defining the 3D path along which the profile is swept. Minimum 2 points required.
path: [
  new Vector3(0, 0, 0),
  new Vector3(0, 5, 0),
  new Vector3(5, 5, 0),
  new Vector3(5, 10, 0)
]
profile
Vector3[]
required
Array of points defining the 2D profile to be swept. Minimum 3 points required. Profile should be defined on a plane perpendicular to the initial path direction.
profile: [
  new Vector3(-0.5, 0, -0.5),
  new Vector3(0.5, 0, -0.5),
  new Vector3(0.5, 0, 0.5),
  new Vector3(-0.5, 0, 0.5)
]
color
number
required
Hexadecimal color value for the swept shape.
color: 0x00ff00  // Green
capStart
boolean
default:"true"
Whether to add a cap (face) at the start of the sweep.
capStart: true  // Close the start
capEnd
boolean
default:"true"
Whether to add a cap (face) at the end of the sweep.
capEnd: true  // Close the end

Methods

setConfig()

Updates the sweep configuration with path and profile, using default caps (both true).
sweep.setConfig(options: ISweepOptions): void
Example:
sweep.setConfig({
  path: [
    new Vector3(0, 0, 0),
    new Vector3(0, 10, 0)
  ],
  profile: [
    new Vector3(-1, 0, -1),
    new Vector3(1, 0, -1),
    new Vector3(1, 0, 1),
    new Vector3(-1, 0, 1)
  ],
  color: 0x3498db
});

getBrep()

Returns the B-Rep (Boundary Representation) data as a parsed JSON object.
sweep.getBrep(): object
Example:
const brepData = sweep.getBrep();
console.log('Vertices:', brepData.vertices.length);
console.log('Faces:', brepData.faces.length);

generateGeometry()

Regenerates the THREE.js geometry from the current configuration. Called automatically after setConfig().
sweep.generateGeometry(): void

discardGeometry()

Disposes of the current geometry to free memory.
sweep.discardGeometry(): void

Properties

ogid
string
Unique identifier for the sweep instance.
options
ISweepOptions
Current sweep configuration including path, profile, color, and cap settings.
const pathLength = sweep.options.path.length;
const profilePoints = sweep.options.profile.length;
color
number
Get or set the sweep color.
sweep.color = 0xff0000;  // Change to red
outline
boolean
Enable or disable outline rendering for the sweep edges.
sweep.outline = true;   // Show wireframe
sweep.outline = false;  // Hide wireframe

Usage Examples

Simple Pipe

import { Sweep, Vector3 } from 'opengeometry';

// Straight vertical pipe with square cross-section
const pipe = new Sweep({
  path: [
    new Vector3(0, 0, 0),
    new Vector3(0, 10, 0)
  ],
  profile: [
    new Vector3(-0.5, 0, -0.5),
    new Vector3(0.5, 0, -0.5),
    new Vector3(0.5, 0, 0.5),
    new Vector3(-0.5, 0, 0.5)
  ],
  color: 0x2ecc71,
  capStart: true,
  capEnd: true
});

scene.add(pipe);

Curved Tube

import { Sweep, Vector3 } from 'opengeometry';

// Create a curved path
const curvedPath = [];
for (let i = 0; i <= 20; i++) {
  const t = i / 20;
  curvedPath.push(new Vector3(
    Math.cos(t * Math.PI) * 5,
    t * 10,
    Math.sin(t * Math.PI) * 5
  ));
}

// Circular profile
const circularProfile = [];
const segments = 12;
for (let i = 0; i < segments; i++) {
  const angle = (i / segments) * Math.PI * 2;
  circularProfile.push(new Vector3(
    Math.cos(angle) * 0.5,
    0,
    Math.sin(angle) * 0.5
  ));
}

const tube = new Sweep({
  path: curvedPath,
  profile: circularProfile,
  color: 0x3498db,
  capStart: true,
  capEnd: true
});

tube.outline = true;

Handrail

import { Sweep, Vector3 } from 'opengeometry';

// Staircase handrail path
const handrailPath = [
  new Vector3(0, 0, 0),
  new Vector3(0, 2, 2),
  new Vector3(0, 4, 4),
  new Vector3(0, 6, 6),
  new Vector3(0, 8, 8)
];

// Circular handrail profile
const handrailProfile = [];
for (let i = 0; i < 16; i++) {
  const angle = (i / 16) * Math.PI * 2;
  handrailProfile.push(new Vector3(
    Math.cos(angle) * 0.3,
    0,
    Math.sin(angle) * 0.3
  ));
}

const handrail = new Sweep({
  path: handrailPath,
  profile: handrailProfile,
  color: 0x8b4513,
  capStart: true,
  capEnd: true
});

Open-Ended Sweep

import { Sweep, Vector3 } from 'opengeometry';

// Sweep without end caps (open tube)
const openTube = new Sweep({
  path: [
    new Vector3(0, 0, 0),
    new Vector3(5, 0, 0),
    new Vector3(5, 5, 0)
  ],
  profile: [
    new Vector3(-0.5, 0, -0.5),
    new Vector3(0.5, 0, -0.5),
    new Vector3(0.5, 0, 0.5),
    new Vector3(-0.5, 0, 0.5)
  ],
  color: 0xe74c3c,
  capStart: false,  // No start cap
  capEnd: false     // No end cap
});

Architectural Molding

import { Sweep, Vector3 } from 'opengeometry';

// Complex profile for decorative molding
const moldingProfile = [
  new Vector3(0, 0, 0),
  new Vector3(0.2, 0, 0.1),
  new Vector3(0.3, 0, 0.1),
  new Vector3(0.4, 0, 0.3),
  new Vector3(0.5, 0, 0.3),
  new Vector3(0.6, 0, 0)
];

// Path around a room corner
const roomPath = [
  new Vector3(0, 8, 0),
  new Vector3(10, 8, 0),
  new Vector3(10, 8, 10)
];

const molding = new Sweep({
  path: roomPath,
  profile: moldingProfile,
  color: 0xf5f5dc,
  capStart: false,
  capEnd: false
});

Implementation Details

Sweep Algorithm

The sweep operation positions the profile at each path point and connects adjacent profiles: Rust Implementation: /workspace/source/main/opengeometry/src/primitives/sweep.rs:92-99
let options = SweepOptions {
    cap_start: self.cap_start,
    cap_end: self.cap_end,
};

self.brep = sweep_profile_along_path(&self.path_points, &self.profile_points, options);

Material Configuration

Sweeps use MeshStandardMaterial with transparency: Source: /workspace/source/main/opengeometry/src/shapes/sweep.ts:123-127
const material = new THREE.MeshStandardMaterial({
  color: this.options.color,
  transparent: true,
  opacity: 0.6,
});

Validation

The sweep validates path and profile requirements: Source: /workspace/source/main/opengeometry/src/shapes/sweep.ts:75-87
validateOptions() {
  if (!this.options) {
    throw new Error("Options are not defined for Sweep");
  }

  if (this.options.path.length < 2) {
    throw new Error("Sweep path requires at least 2 points.");
  }

  if (this.options.profile.length < 3) {
    throw new Error("Sweep profile requires at least 3 points.");
  }
}

Cap Generation

When capStart or capEnd is true, the sweep operation adds triangulated faces at the ends: Source: /workspace/source/main/opengeometry/src/shapes/sweep.ts:95-96

Best Practices

Profile Orientation: Define the profile on a plane perpendicular to the initial path direction. For paths starting along the Y-axis, define profiles on the XZ plane.
Path Smoothness: Sharp angles in the path may cause geometry artifacts. For smoother results, use more path points with gradual direction changes.
Profile Complexity: Complex profiles with many points will generate more geometry. Balance profile detail with performance requirements.
Closed Profiles: For hollow tubes, ensure the profile forms a closed loop by making the first and last points identical.

Performance Considerations

Vertex Count

Total vertices ≈ path_points × profile_points

Face Count

Total faces ≈ (path_points - 1) × profile_points × 2 + cap_faces

Optimization Tips

  1. Reduce Path Points: Use fewer points for distant or less important sweeps
  2. Simplify Profiles: Use simpler profiles (fewer vertices) when high detail isn’t needed
  3. Disable Caps: Set capStart and capEnd to false for open-ended shapes
  4. Outline Toggle: Only enable outlines when needed for debugging or emphasis

Live Demo

Sweep Demo

Try the Sweep shape in the browser

See Also

Cylinder

Simple straight extrusions

Polygon

Custom 2D profiles

Cuboid

Rectangular extrusions
Last modified on March 14, 2026