# How to Perform Visual Collision Checking Between CAD Parts in text-to-cad

> Learn visual collision checking between CAD parts using text-to-cad. Parse URDF/SDF, load meshes, and run runtime queries with MoveIt2 for precise robot design.

- Repository: [earthtojake/text-to-cad](https://github.com/earthtojake/text-to-cad)
- Tags: how-to-guide
- Published: 2026-07-29

---

**The text-to-cad repository implements visual collision checking by parsing URDF/SDF files to separate visual and collision geometry, loading meshes via Python URDF sources, and executing runtime collision queries through a MoveIt2 planning scene that respects SRDF disabled collision pairs.**

The text-to-cad pipeline enables roboticists and CAD designers to verify that mechanical parts do not intersect before fabrication. This article examines how the repository handles visual collision checking by coordinating JavaScript parsers, Python mesh loaders, and the MoveIt2 motion planning framework. Understanding this architecture allows you to programmatically validate CAD assemblies and prevent physical collisions in robotic applications.

## Understanding the Collision Checking Architecture

The collision checking system operates through five distinct layers that convert raw CAD definitions into actionable collision reports. Each layer handles a specific transformation from XML parsing to geometric intersection testing.

- **URDF/SDF Parsing**: JavaScript utilities in [`packages/cadjs/src/lib/urdf/parseSdf.js`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadjs/src/lib/urdf/parseSdf.js) extract `<visual>` and `<collision>` elements and resolve mesh URLs, while [`parseSrdf.js`](https://github.com/earthtojake/text-to-cad/blob/main/parseSrdf.js) manages disabled collision pairs.

- **Python URDF Sources**: The `UrdfSource` class in [`skills/urdf/scripts/urdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/source.py) (lines 60-109) builds objects containing `visual_mesh_paths` and `collision_mesh_paths`, while [`skills/sdf/scripts/sdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/sdf/scripts/sdf/source.py) handles SDF equivalents.

- **SRDF Configuration**: The `SrdfSource` class in [`skills/srdf/scripts/srdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/srdf/scripts/srdf/source.py) (lines 70-212) interprets `<disable_collisions>` entries that instruct the system to ignore specific contact pairs.

- **MoveIt2 Integration**: The planning scene server in [`viewer/moveit2_server/moveit2_server/context.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/moveit2_server/moveit2_server/context.py) (lines 442-713) creates `CollisionObject` instances and performs runtime geometric queries.

- **Export Validation**: The generation module in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) (lines 548-572) aborts exports if mesh intersections are detected during file conversion.

## Parsing Visual and Collision Geometry

The collision checking process begins in the JavaScript parsing layer where URDF and SDF files are analyzed to distinguish between visual representation and physical collision boundaries.

In [`packages/cadjs/src/lib/urdf/parseSdf.js`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadjs/src/lib/urdf/parseSdf.js), line 251 implements the logic that determines mesh classification:

```javascript
labelKind = kind === "collision" ? "collision" : "visual"

```

When a `<link>` element contains only a `<visual>` child, the parser automatically uses the visual mesh for collision calculations. This default behavior ensures that every link possesses collision geometry even when designers omit explicit `<collision>` tags. The parser collects these mesh URLs and maintains separate arrays for visual and collision types within each link object.

For SRDF processing, [`packages/cadjs/src/lib/urdf/parseSrdf.js`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadjs/src/lib/urdf/parseSrdf.js) handles collision pair exclusions. Lines 392-408 validate `<disable_collisions>` entries, ensuring that specified link pairs are properly formatted before reaching the MoveIt2 planning scene.

## Loading Mesh Data with Python URDF Sources

After parsing, the Python layer transforms file paths into structured mesh sources ready for geometric computation. The `UrdfSource` class in [`skills/urdf/scripts/urdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/urdf/scripts/urdf/source.py) (lines 60-109) populates two critical attributes:

- `visual_mesh_paths`: References to meshes used for rendering
- `collision_mesh_paths`: References to simplified meshes used for intersection testing

If collision meshes are unspecified, the system falls back to visual geometry for intersection checks. The `SrdfSource` class in [`skills/srdf/scripts/srdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/srdf/scripts/srdf/source.py) (lines 70-212) complements this by parsing `SrdfDisabledCollisionPair` objects that represent intentional mechanical contacts between adjacent parts.

## Runtime Collision Checking with MoveIt2

The actual geometric intersection testing occurs within the MoveIt2 planning framework. The `MoveIt2Context` class in [`viewer/moveit2_server/moveit2_server/context.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/moveit2_server/moveit2_server/context.py) (lines 442-713) initializes a planning scene containing `CollisionObject` instances for each link's collision geometry.

When performing collision queries, the system checks all enabled collision pairs while automatically excluding those listed in the SRDF configuration. This allows the collision checker to ignore intentional contacts between connected joints while flagging unintended intersections between moving parts.

The collision checking API exposes methods to query specific link pairs, returning boolean results indicating whether geometric overlap exists between the specified CAD components.

## Export-Time Safety Validation

Beyond runtime checking, text-to-cad validates collisions during file export operations. The generation module in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) (lines 548-572) implements a safety check that aborts the export process if converted meshes would intersect in the output format.

The code raises a `Native GLB output collision` error (line 572) when the generator detects mesh intersections, preventing the creation of physically impossible assemblies in exported GLB, STL, or 3MF files.

## Implementation Examples

### Querying Collisions in Python

The following example demonstrates loading URDF/SRDF sources and checking for collisions between specific links:

```python
from skills.urdf.scripts.urdf.source import UrdfSource
from skills.srdf.scripts.srdf.source import SrdfSource
from viewer.moveit2_server.moveit2_server.context import MoveIt2Context
from pathlib import Path

# Load URDF and SRDF sources

urdf_src = UrdfSource(source_path=Path("models/robot.urdf"))
srdf_src = SrdfSource(source_path=Path("models/robot.srdf"))

# Initialize MoveIt2 planning context

ctx = MoveIt2Context(
    urdf_source=urdf_src,
    srdf_source=srdf_src,
    # Additional required arguments omitted for brevity

)

# Check collision between specific links

is_colliding = ctx.check_collision("base_link", "wrist")
print(f"Collision detected: {is_colliding}")

```

### Inspecting Parsed Geometry in JavaScript

For web-based viewers, inspect parsed collision meshes using the SDF parser:

```javascript
import { parseSdf } from "./packages/cadjs/src/lib/urdf/parseSdf.js";

const sdfData = parseSdf(sdfXml, { sourceUrl: "/models/robot.sdf" });

sdfData.links.forEach(link => {
  console.log(`${link.name} collision meshes:`, 
    link.collisions.map(c => c.meshUrl));
});

```

### Disabling Known Collision Pairs

Exclude adjacent links from collision checking by adding entries to your SRDF file:

```xml
<disable_collisions link1="base_link" link2="shoulder_link" reason="adjacent"/>

```

According to the source code in [`skills/srdf/scripts/srdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/srdf/scripts/srdf/source.py), these entries create `SrdfDisabledCollisionPair` objects that the MoveIt2 server respects during planning scene initialization.

## Summary

- **Separate geometry types**: The text-to-cad pipeline distinguishes between visual meshes for rendering and collision meshes for intersection testing, falling back to visual geometry when collision meshes are unspecified.

- **Multi-layer architecture**: Collision checking flows from JavaScript URDF/SDF parsers through Python source objects to the MoveIt2 planning scene, with SRDF configuration controlling which pairs to ignore.

- **Runtime and export validation**: The system checks for collisions both during MoveIt2 planning queries and during mesh export operations, preventing the generation of physically intersecting CAD assemblies.

- **Disabled collision support**: SRDF files define intentional contacts between adjacent parts using `<disable_collisions>` tags, which the parser validates and the MoveIt2 server respects during geometric queries.

## Frequently Asked Questions

### What happens if a URDF link lacks explicit collision geometry?

When a `<link>` element contains only `<visual>` tags, the JavaScript parser in [`packages/cadjs/src/lib/urdf/parseSdf.js`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadjs/src/lib/urdf/parseSdf.js) (line 251) automatically uses the visual mesh for collision calculations. The Python `UrdfSource` class then populates `collision_mesh_paths` with the visual mesh paths, ensuring every link participates in collision checking.

### How do I exclude specific part pairs from collision detection?

Add `<disable_collisions link1="part_a" link2="part_b" reason="adjacent"/>` entries to your SRDF file. The `SrdfSource` class in [`skills/srdf/scripts/srdf/source.py`](https://github.com/earthtojake/text-to-cad/blob/main/skills/srdf/scripts/srdf/source.py) (lines 70-212) parses these into `SrdfDisabledCollisionPair` objects. When initializing the `MoveIt2Context` in [`viewer/moveit2_server/moveit2_server/context.py`](https://github.com/earthtojake/text-to-cad/blob/main/viewer/moveit2_server/moveit2_server/context.py), these pairs are automatically excluded from collision queries.

### Can collision checking run during mesh export to GLB or STL?

Yes. The generation module in [`packages/cadpy/src/cadpy/generation.py`](https://github.com/earthtojake/text-to-cad/blob/main/packages/cadpy/src/cadpy/generation.py) (lines 548-572) performs collision validation during the export process. If the code detects intersecting meshes when generating GLB, STL, or 3MF files, it raises a "Native GLB output collision" error and aborts the export to prevent manufacturing physically impossible assemblies.

### What is the difference between visual and collision meshes in the pipeline?

Visual meshes define the high-resolution appearance of parts for rendering, while collision meshes provide simplified geometric representations optimized for fast intersection calculations. The `UrdfSource` class stores these separately in `visual_mesh_paths` and `collision_mesh_paths` attributes. MoveIt2 uses collision meshes exclusively for planning scene queries, whereas export validators check both types depending on availability.