Thank you for your interest in contributing to Scientific Visualizer! This document provides guidelines and instructions for contributing to the project.
This is currently a portfolio/learning project in active development. We're building this in phases:
- ✅ Phase 1 (Complete): Foundation & GPU Context
- ✅ Phase 2 (Complete): Camera & Math System
- ✅ Phase 3 (Complete): Basic Data & Rendering
- ✅ Phase 4 (Complete): UI Integration
- 🚧 Phase 5 (Next): Colormap System
- 📋 Phase 6-10: See ROADMAP.md
-
Performance First: This is a high-performance visualization library
- Target: 1M+ points @ 60 FPS
- Profile before optimizing, but optimize aggressively
- Use GPU for heavy lifting
-
Production-Grade Code
- This is NOT a learning project - write production code
- Comprehensive error handling (no unwraps in production code)
- Full documentation for all public APIs
- Tests for all major features
-
Clean Architecture
- Modular design with clear separation of concerns
- Follow Rust best practices and idioms
- Prefer explicit over implicit
- Zero unsafe code (except where required by GPU interop)
- Rust 1.75+ (latest stable)
- A GPU (for testing)
- Git
# Clone the repository
git clone https://github.com/yourusername/scientific-visualizer
cd scientific-visualizer
# Build the project
cargo build --workspace
# Run tests
cargo test --workspace
# Run examples
cargo run -p examples --bin basic_window
cargo run -p examples --bin camera_movement
cargo run -p examples --bin scatter_3d
cargo run -p examples --bin scatter_3d_uiRecommended tools:
# Auto-rebuild on changes
cargo install cargo-watch
cargo watch -x check
# Linting
cargo clippy --workspace
# Code formatting
cargo fmt --all
# Documentation
cargo doc --open --workspacemain: Stable, completed phases onlyphase-N: Active development for Phase Nfeature/description: Specific features
-
Create phase branch from main:
git checkout main git pull git checkout -b phase-2
-
Develop with small, focused commits:
git add -p # Review changes before committing git commit -m "feat(camera): implement orbital camera view matrix"
-
Merge to main when phase complete:
# Ensure all tests pass cargo test --workspace cargo clippy --workspace # Update CHANGELOG.md # Update README.md status git checkout main git merge phase-2 git push
Follow conventional commits:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringperf: Performance improvementstest: Adding/updating testschore: Maintenance tasks
Examples:
feat(renderer): add GPU instancing for scatter plots
fix(camera): correct aspect ratio calculation
docs(api): add examples for PointCloud API
perf(scatter): optimize vertex buffer updates
- Follow Rust 2021 edition idioms
- Run
cargo fmtbefore committing - Fix all
cargo clippywarnings - Document all public APIs with rustdoc
/// Renders a 3D scatter plot with GPU acceleration.
///
/// # Performance
/// Can render 1M+ points at 60 FPS using GPU instancing.
///
/// # Examples
/// ```
/// use viz_core::RenderContext;
/// use viz_plots::Scatter3D;
///
/// let scatter = Scatter3D::new(&context, point_cloud)?;
/// scatter.render(&mut render_pass);
/// ```
///
/// # Errors
/// Returns `RenderError::OutOfMemory` if GPU allocation fails.
pub fn render(&self, render_pass: &mut wgpu::RenderPass) -> Result<()> {
// Implementation
}// ✅ Good - use thiserror for custom errors
#[derive(Debug, thiserror::Error)]
pub enum PlotError {
#[error("Invalid data: {0}")]
InvalidData(String),
#[error("Render error: {0}")]
RenderError(#[from] RenderError),
}
// ✅ Good - propagate errors with ?
pub fn load_data(path: &Path) -> Result<PointCloud, DataError> {
let file = File::open(path)?;
let data = parse_csv(file)?;
Ok(PointCloud::new(data))
}
// ❌ Bad - don't use unwrap in library code
pub fn bad_example(path: &Path) -> PointCloud {
let file = File::open(path).unwrap(); // DON'T DO THIS
// ...
}// ✅ Good - minimize allocations
pub fn process_data(&self, points: &[Vec3]) -> Vec<Vec4> {
points.iter()
.map(|p| self.transform(p))
.collect()
}
// ✅ Good - use rayon for parallel processing
use rayon::prelude::*;
pub fn parallel_process(&self, points: &[Vec3]) -> Vec<Vec4> {
points.par_iter()
.map(|p| self.transform(p))
.collect()
}
// ❌ Bad - unnecessary clones
pub fn bad_example(&self, points: &[Vec3]) -> Vec<Vec4> {
let cloned = points.to_vec(); // Unnecessary allocation
cloned.iter().map(|p| self.transform(p)).collect()
}- Unit tests for all core functionality
- Integration tests for rendering pipeline
- Benchmarks for performance-critical code
- Examples that demonstrate features
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_relative_eq;
#[test]
fn test_camera_view_matrix() {
let camera = OrbitalCamera::new(Vec3::ZERO, 10.0);
let view = camera.view_matrix();
// Test properties of view matrix
assert_relative_eq!(view.determinant(), 1.0, epsilon = 1e-6);
}
}use criterion::{criterion_group, criterion_main, Criterion};
fn benchmark_scatter_render(c: &mut Criterion) {
let mut group = c.benchmark_group("scatter");
group.bench_function("1M points", |b| {
b.iter(|| {
// Benchmark code
});
});
group.finish();
}
criterion_group!(benches, benchmark_scatter_render);
criterion_main!(benches);- README.md - Keep updated with current status
- CHANGELOG.md - Document all changes
- API docs - Rustdoc for all public items
- Architecture docs - Update when design changes
- Examples - One example per major feature
# Generate and view docs
cargo doc --open --workspace --no-deps
# Check for missing docs
cargo rustdoc -- -D missing_docs-
Create feature branch
git checkout -b feature/my-feature
-
Make changes with tests
- Write code
- Add tests
- Update documentation
- Add example if needed
-
Ensure quality
cargo test --workspace cargo clippy --workspace -- -D warnings cargo fmt --all -- --check -
Update CHANGELOG.md
-
Submit PR with description
- What does this change?
- Why is it needed?
- How was it tested?
-
Address review feedback
# Run all benchmarks
cargo bench --workspace
# Run specific benchmark
cargo bench --bench rendering_perf
# Generate flamegraph (requires cargo-flamegraph)
cargo flamegraph --bench rendering_perf- Frame time: <10ms (60+ FPS)
- 1M points: 60 FPS
- 10M points: 30 FPS
- GPU memory: <2GB for 10M points
- Check README.md for overview
- Read ARCHITECTURE.md for design
- See ROADMAP.md for project plan
- Open an issue for questions
Be respectful and constructive. This is a learning-focused project - help others learn and grow.
By contributing, you agree that your contributions will be licensed under the MIT License.