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-three';

// 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-three';

// 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-three';

// 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-three';

// 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-three';

// 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-three/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-three/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-three/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

See Also

  • Cylinder - For simple straight extrusions
  • Polygon - For creating custom 2D profiles
  • Cuboid - For rectangular extrusions
Last modified on March 7, 2026