hoops_ai.insights

Data Analysis and Visualization Module

The Insights module provides comprehensive data analysis and visualization capabilities for CAD datasets, machine learning results, and geometric data. It bridges the gap between complex CAD data processing and intuitive visual understanding, offering both interactive exploration tools and automated analysis workflows.

This module enables researchers, engineers, and data scientists to gain deep insights into CAD data patterns, model performance, geometric relationships, and dataset characteristics through rich visualizations and statistical analysis.

For visualization techniques and analysis workflows, see the CAD Data Visualization Programming Guide.

class hoops_ai.insights.CADViewer(host='127.0.0.1', port=None, static_folder=None, display_mode='sidecar', auto_display=False, silent=True)

Bases: object

High-level CAD viewer with HOOPS AI integration.

This class provides a simple interface for viewing CAD models in Jupyter notebooks with automatic resource management and display handling.

Parameters:
  • host (str) – Host address for viewer server (default: ‘127.0.0.1’)

  • port (int | None) – Port for viewer server. If None (default), automatically finds a free port starting from 8000. If specified, uses that exact port (will fail if port is busy).

  • static_folder (Path | None) – Path to static folder for serving files

  • display_mode (str) – Display mode (‘sidecar’, ‘inline’, ‘none’)

  • auto_display (bool) – Whether to automatically display on load

  • silent (bool) – Whether to suppress server output

Examples

>>> # Basic usage:
>>> viewer = CADViewer()
>>> viewer.load_cad_file("model.step")
>>> viewer.show()
>>>
>>> # With context manager:
>>> with CADViewer() as viewer:
>>>     viewer.load_cad_file("model.step")
>>>     viewer.show()
>>>
>>> # Sidecar display:
>>> viewer = CADViewer(display_mode='sidecar')
>>> viewer.load_cad_file("model.step")
>>> viewer.show()
clear_face_colors()

Clear all face colors.

Removes all color highlighting from faces, returning them to default appearance.

color_faces_by_groups(face_groups, delay=0.3, clear_first=True, verbose=True)

Color faces by groups with progress feedback.

This method colors multiple groups of faces, where each group has a list of face indices, an RGB color, and a description.

Parameters:
  • face_groups (List[Tuple[List[int], Tuple[int, int, int], str]]) – List of (face_indices, color, description) tuples where color is (R, G, B) tuple with 0-255 values

  • delay (float) – Seconds to pause between coloring different groups (visual effect)

  • clear_first (bool) – Whether to clear existing colors before applying new ones

  • verbose (bool) – Whether to print progress with colored terminal indicators

Examples

>>> groups = [
...     ([1, 2, 6], (255, 0, 0), 'through hole'),
...     ([3, 5], (0, 0, 255), 'blind hole')
... ]
>>> viewer.color_faces_by_groups(groups, delay=0.5)
🟥 through hole (3 faces)
🟦 blind hole (2 faces)
get_selected_faces()

Get face indices selected by user in the viewer.

User should: 1. Click on a face in the 3D view to highlight it 2. Use Ctrl+Click to highlight multiple faces 3. Call this method to retrieve the selection

Returns:

List of selected face indices

Return type:

List[int]

Examples

>>> selected = viewer.get_selected_faces()
>>> print(f"Selected {len(selected)} faces: {selected}")
>>> viewer.set_face_color(selected, [0, 255, 0])  # Color them green
get_status()

Get comprehensive viewer status information.

Returns:

Dictionary containing viewer state information

Return type:

Dict[str, Any]

Examples

>>> status = viewer.get_status()
>>> print(f"Active: {status['active']}")
>>> print(f"Model loaded: {status['model_loaded']}")
get_viewer_url()

Get the viewer server URL.

Returns:

Viewer URL if active, None otherwise

Return type:

str | None

Examples

>>> url = viewer.get_viewer_url()
>>> print(f"Viewer running at: {url}")
property is_active: bool

Check if viewer is active and running.

property is_model_loaded: bool

Check if a model is currently loaded in the viewer.

load_cad_file(filepath, auto_convert=True, white_background=True)

Load a CAD file for viewing.

Parameters:
  • filepath (str) – Path to the CAD file

  • auto_convert (bool) – Whether to automatically convert CAD to SCS format (default: True)

  • white_background (bool) – Whether to use white background for conversion (default: True)

Returns:

True if loading was successful, False otherwise

Return type:

bool

load_scs_file(filepath)

Load an SCS file directly (no conversion needed).

Parameters:

filepath (str) – Path to the SCS file

Returns:

True if loading was successful, False otherwise

Return type:

bool

set_face_color(face_indices, color=None)

Set color for specific faces.

Parameters:
  • face_indices (List[int]) – List of face indices to color

  • color (List[int] | None) – RGB color as [r, g, b] (0-255). If None, uses default highlight.

Examples

>>> viewer.set_face_color([0, 1, 2])  # Default color
>>> viewer.set_face_color([0, 1, 2], [255, 0, 0])  # Red
show(display_mode=None, **display_kwargs)

Display the viewer in Jupyter.

Parameters:
  • display_mode (str | None) – Display mode (‘sidecar’, ‘inline’, ‘none’). If None, uses instance default.

  • **display_kwargs – Additional arguments for display functions

Returns:

DisplayHandle or None

Return type:

DisplayHandle | None

terminate()

Terminate the viewer and clean up resources.

This method should be called when done with the viewer to properly shut down the server and release resources.

static validate_color(color)

Validate RGB color values.

Parameters:

color (List[int]) – RGB color as [r, g, b]

Returns:

True if color is valid (3 integers, 0-255), False otherwise

Return type:

bool

Examples

>>> CADViewer.validate_color([255, 0, 0])  # True
>>> CADViewer.validate_color([255, 0, 256])  # False (out of range)
>>> CADViewer.validate_color([255, 0])  # False (wrong length)
class hoops_ai.insights.DatasetViewer(file_ids, png_paths, scs_paths, file_names=None)

Bases: object

Powerful visualization tool for exploring CAD datasets.

This class accepts lists of file IDs and their corresponding visualization paths to enable visualization of CAD files as either: 1. Image collages/grids using PNG previews 2. Interactive 3D views using stream cache files

The DatasetViewer is designed to work with data from DatasetExplorer but remains decoupled, accepting only the necessary lists for maximum flexibility.

Examples

>>> # Get data from explorer
>>> explorer = DatasetExplorer(flow_output_file="flow.json")
>>> cache_df = explorer.get_stream_cache_paths()
>>>
>>> # Extract lists
>>> file_ids = cache_df['id'].tolist()
>>> png_paths = cache_df['stream_cache_png'].tolist()
>>> scs_paths = cache_df['stream_cache_3d'].tolist()
>>> file_names = cache_df['name'].tolist()
>>>
>>> # Create viewer
>>> viewer = DatasetViewer(file_ids, png_paths, scs_paths, file_names)
>>>
>>> # Or use convenience method
>>> viewer = DatasetViewer.from_explorer(explorer)
>>>
>>> # Query files and visualize
>>> query_ids = explorer.get_file_list(group="graph", where=lambda ds: ds['num_nodes'] > 30)
>>> viewer.show_preview_as_image(query_ids, k=25)
Parameters:
create_comparison_view(file_id_a, file_id_b, display_mode='sidecar', host='127.0.0.1', silent=True)

Create side-by-side comparison of two files.

This is useful for comparing similar parts, analyzing variations, or examining before/after scenarios.

Parameters:
  • file_id_a (int) – First file ID to compare

  • file_id_b (int) – Second file ID to compare

  • display_mode (str) – Display mode for viewers (default: ‘sidecar’)

  • host (str) – Host address for viewer servers (default: ‘127.0.0.1’)

  • silent (bool) – Whether to suppress viewer server output (default: True)

Returns:

Tuple of (viewer_a, viewer_b) or (None, None) if failed

Return type:

Tuple[CADViewer | None, CADViewer | None]

Examples

>>> # Compare two files side by side
>>> viewer_a, viewer_b = dataset_viewer.create_comparison_view(42, 87)
>>>
>>> # Highlight same features in both
>>> viewer_a.set_face_color([1, 2, 3], [255, 0, 0])
>>> viewer_b.set_face_color([1, 2, 3], [255, 0, 0])
>>>
>>> # Clean up
>>> viewer_a.terminate()
>>> viewer_b.terminate()
filter_by_availability(file_ids, require_png=False, require_3d=False)

Filter file IDs based on visualization data availability.

This is useful to ensure you only try to visualize files that have the necessary visualization data available.

Parameters:
  • file_ids (List[int]) – List of file IDs to filter

  • require_png (bool) – If True, only return IDs with PNG previews (default: False)

  • require_3d (bool) – If True, only return IDs with 3D stream cache (default: False)

Returns:

Filtered list of file IDs

Return type:

List[int]

Examples

>>> # Get files that have PNG previews
>>> files_with_images = viewer.filter_by_availability(
...     all_file_ids,
...     require_png=True
... )
>>>
>>> # Get files that have both PNG and 3D
>>> fully_visualizable = viewer.filter_by_availability(
...     all_file_ids,
...     require_png=True,
...     require_3d=True
... )
classmethod from_explorer(explorer)

Convenience constructor to create DatasetViewer from a DatasetExplorer.

This method queries the explorer for stream cache paths and creates a DatasetViewer with the extracted data.

Parameters:

explorer (DatasetExplorer) – DatasetExplorer instance

Returns:

DatasetViewer instance

Return type:

DatasetViewer

Examples

>>> explorer = DatasetExplorer(flow_output_file="flow.json")
>>> viewer = DatasetViewer.from_explorer(explorer)
>>> viewer.print_statistics()
get_available_file_ids()

Get list of all file IDs that have visualization data available.

Returns:

List of file IDs with PNG or stream cache paths

Return type:

List[int]

Examples

>>> available_ids = viewer.get_available_file_ids()
>>> print(f"Files with visualization: {len(available_ids)}")
get_file_info(file_id)

Get visualization information for a specific file ID.

Parameters:

file_id (int) – File ID to query (int or convertible to int)

Returns:

Dictionary with ‘name’, ‘png_path’, ‘stream_cache_path’ or None if not found

Return type:

Dict[str, Any] | None

Examples

>>> info = viewer.get_file_info(42)
>>> print(f"File name: {info['name']}")
>>> print(f"PNG available: {info['png_path'] is not None}")
get_statistics()

Get statistics about available visualization data.

Returns:

Dictionary containing statistics about the dataset visualization data

Return type:

Dict[str, Any]

Examples

>>> stats = viewer.get_statistics()
>>> print(f"Total files: {stats['total_files']}")
>>> print(f"PNG available: {stats['files_with_png']}")
>>> print(f"3D cache available: {stats['files_with_3d']}")
>>> print(f"Coverage: {stats['coverage_percentage']:.1f}%")
print_statistics()

Print formatted statistics about visualization data availability.

Examples

>>> viewer.print_statistics()

Dataset Visualization Statistics ═══════════════════════════════════════════════ Total files: 234 Files with PNG preview: 234 (100.0%) Files with 3D cache: 234 (100.0%) Overall coverage: 100.0%

Return type:

None

refresh_mapping(file_ids, png_paths, scs_paths, file_names=None)

Refresh the internal file mapping with new data.

Use this method if the dataset has been updated or you want to update the visualization paths.

Parameters:
  • file_ids (List[int]) – List of file IDs

  • png_paths (List[str | None]) – List of PNG paths

  • scs_paths (List[str | None]) – List of SCS paths

  • file_names (List[str] | None) – Optional list of file names

Return type:

None

Examples

>>> # Update with new data
>>> viewer.refresh_mapping(new_ids, new_pngs, new_scs, new_names)
>>> print(f"Refreshed mapping contains {len(viewer._file_mapping)} files")
show_preview_as_3d(file_ids, k=5, display_mode='inline', layout='sequential', host='127.0.0.1', start_port=8000, silent=True, width=400, height=400)

Open interactive 3D viewers for file IDs using stream cache files.

This method creates CADViewer instances for each file, loading their 3D stream cache representations. Users can interact with the 3D models directly in the notebook.

Parameters:
  • file_ids (List[int]) – List of file IDs to visualize (ints, numpy array, or convertible to int)

  • k (int) – Maximum number of 3D viewers to open (default: 5)

  • display_mode (str) – Display mode - ‘inline’, ‘sidecar’, or ‘none’ (default: ‘inline’)

  • layout (str) – Layout strategy - ‘sequential’ or ‘grid’ (default: ‘sequential’) Note: ‘grid’ not yet implemented, uses sequential

  • host (str) – Host address for viewer servers (default: ‘127.0.0.1’)

  • start_port (int) – Starting port for viewer servers (default: 8000)

  • silent (bool) – Whether to suppress viewer server output (default: True)

  • width (int) – Width of inline viewer in pixels (default: 400)

  • height (int) – Height of inline viewer in pixels (default: 400)

Returns:

List of CADViewer instances (one per displayed file)

Return type:

List[CADViewer]

Examples

>>> # Open 3 compact inline 3D viewers (forms a grid-like layout)
>>> viewers = viewer.show_preview_as_3d(file_ids, k=3)
>>>
>>> # Open larger inline viewers
>>> viewers = viewer.show_preview_as_3d(
...     file_ids,
...     k=3,
...     width=600,
...     height=500
... )
>>>
>>> # Open viewers in sidecar layout (full size)
>>> viewers = viewer.show_preview_as_3d(
...     file_ids,
...     k=5,
...     display_mode='sidecar'
... )
>>>
>>> # Interact with specific viewer
>>> selected_faces = viewers[0].get_selected_faces()
>>> viewers[0].set_face_color(selected_faces, [255, 0, 0])
>>>
>>> # Clean up viewers when done
>>> for v in viewers:
...     v.terminate()
show_preview_as_image(file_ids, k=25, grid_cols=6, figsize=(15, 5), show_labels=True, label_format='id', title=None, missing_color=(200, 200, 200), save_path=None)

Generate an image grid visualization from file IDs.

This method creates a matplotlib figure displaying PNG previews of CAD files in a grid layout. It’s perfect for quickly visualizing query results.

Parameters:
  • file_ids (List[int]) – List of file IDs to visualize (ints, numpy array, or convertible to int)

  • k (int) – Maximum number of files to display (default: 25)

  • grid_cols (int | None) – Number of columns in grid. If None, auto-calculated (default: None)

  • figsize (Tuple[int, int] | None) – Figure size as (width, height). If None, auto-calculated (default: None)

  • show_labels (bool) – Whether to show file labels on images (default: True)

  • label_format (str) – Label format - ‘id’, ‘name’, or ‘both’ (default: ‘id’)

  • title (str | None) – Overall figure title (default: None)

  • missing_color (Tuple[int, int, int]) – RGB color for files without PNG preview (default: gray)

  • save_path (str | None) – If provided, save the figure to this path (default: None)

Returns:

matplotlib Figure object

Return type:

matplotlib.pyplot.Figure

Examples

>>> # Simple grid visualization
>>> fig = viewer.show_preview_as_image(file_ids, k=16)
>>>
>>> # Custom 4-column grid with names
>>> fig = viewer.show_preview_as_image(
...     file_ids,
...     k=20,
...     grid_cols=4,
...     label_format='name',
...     title='High Complexity Parts'
... )
>>>
>>> # Save to file
>>> fig = viewer.show_preview_as_image(
...     file_ids,
...     k=100,
...     save_path='results/query_visualization.png'
... )
class hoops_ai.insights.DisplayHandle(display_type, widget=None, url=None)

Bases: object

Handle for managing displayed viewer.

Parameters:
  • display_type (str)

  • url (str)

close()

Close the display.

is_active()

Check if display is active.

Return type:

bool

hoops_ai.insights.create_comparison_view(urls, layout='horizontal', titles=None)

Display multiple viewers side-by-side.

Parameters:
  • urls (List[str]) – List of viewer URLs to display

  • layout (str) – Layout type (‘horizontal’, ‘vertical’, ‘grid’)

  • titles (List[str] | None) – Optional list of titles for each viewer

Returns:

DisplayHandle instance

Raises:
Return type:

DisplayHandle

hoops_ai.insights.create_inline_display(url, width=960, height=600)

Create inline display for viewer.

Parameters:
  • url (str) – URL of the viewer to display

  • width (int) – Width of the iframe in pixels

  • height (int) – Height of the iframe in pixels

Returns:

DisplayHandle instance

Raises:

ImportError – If IPython is not available

Return type:

DisplayHandle

hoops_ai.insights.create_sidecar_display(url, title='CAD Viewer', anchor='right', width=450, height=1080)

Create sidecar display for viewer.

Parameters:
  • url (str) – URL of the viewer to display

  • title (str) – Title for the sidecar window

  • anchor (str) – Position of sidecar (‘right’, ‘left’, ‘split-right’, ‘split-left’)

  • width (int) – Width of the sidecar in pixels (only for ‘right’/’left’ anchors)

  • height (int) – Height of the iframe in pixels (ignored for responsive layout)

Returns:

DisplayHandle instance

Raises:

ImportError – If required packages are not available

Return type:

DisplayHandle

hoops_ai.insights.detect_jupyter_environment()

Detect which Jupyter environment we’re running in.

Returns:

‘lab’, ‘notebook’, ‘vscode’, or ‘unknown’

Return type:

str

hoops_ai.insights.find_free_port(start_port=8000, max_attempts=100, host='127.0.0.1')

Find a free port starting from a given port number.

Parameters:
  • start_port (int) – Port number to start searching from (default: 8000)

  • max_attempts (int) – Maximum number of ports to try (default: 100)

  • host (str) – Host address to check (default: ‘127.0.0.1’)

Returns:

First available port number, or None if no port found

Return type:

int

Examples

>>> port = find_free_port()
>>> print(f"Found free port: {port}")
>>> port = find_free_port(start_port=9000)  # Start from 9000
hoops_ai.insights.is_port_available(port, host='127.0.0.1')

Check if a port is available for binding.

Parameters:
  • port (int) – Port number to check

  • host (str) – Host address to check (default: ‘127.0.0.1’)

Returns:

True if port is available, False otherwise

Return type:

bool

hoops_ai.insights.is_viewer_available()

Check if hoops_viewer package is installed.

Returns:

True if hoops_viewer is available, False otherwise

Return type:

bool

hoops_ai.insights.quick_view(filepath, display_mode='sidecar', static_folder=None, **kwargs)

Quick one-liner to view a CAD file.

This convenience function creates a viewer, loads the file, and displays it in a single call. By default, automatically finds a free port.

Parameters:
  • filepath (str) – Path to the CAD file

  • display_mode (str) – Display mode (‘sidecar’, ‘inline’)

  • static_folder (Path | None) – Optional static folder path

  • **kwargs – Additional arguments for CADViewer (e.g., port=9000 for specific port)

Returns:

CADViewer instance

Return type:

CADViewer

Examples

>>> # Auto-find port (default)
>>> viewer = quick_view("model.step")
>>> # Inline display with auto port
>>> viewer = quick_view("model.step", display_mode='inline')
>>> # Specify exact port (strict mode)
>>> viewer = quick_view("model.step", port=9000)

Modules

dataset_viewer

Dataset Viewer Module for HOOPS AI Insights.

utils

Visualization utilities for HOOPS AI Insights.

viewer

Main viewer module for HOOPS AI Insights.