Skip to content

Conversation

MichaelBuessemeyer
Copy link
Contributor

Reverts #8159

Seems like this PR caused error/bug: https://scm.slack.com/archives/C5AKLAV0B/p1737746802362229

@MichaelBuessemeyer MichaelBuessemeyer self-assigned this Jan 24, 2025
Copy link
Contributor

coderabbitai bot commented Jan 24, 2025

📝 Walkthrough

Walkthrough

This pull request introduces significant changes to the dataset transformation and rotation handling in the frontend codebase. The modifications involve restructuring how transformations are managed, removing specific rotation-related components, and consolidating transformation-related functions into a single module. The changes primarily affect how dataset layers are transformed, with a focus on simplifying the import structure and reducing complexity in transformation logic.

Changes

File Path Change Summary
frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts Major refactoring of transformation handling, adding new functions for layer transformations
frontend/javascripts/dashboard/dataset/dataset_rotation_form_item.tsx Completely removed rotation-related components
frontend/javascripts/dashboard/dataset/dataset_settings_* Removed rotation-related settings and configurations
frontend/javascripts/types/api_flow_types.ts Updated transformation type definitions
Multiple files Consolidated imports from dataset_layer_transformation_accessor to dataset_accessor

Possibly related PRs

Suggested Labels

bug, frontend, automerge

Poem

🐰 Transformations dance and sway,
Code refactored in a clever way,
Layers shift without a care,
Rotation settings vanish in the air,
A rabbit's code ballet! 🌈

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@MichaelBuessemeyer MichaelBuessemeyer enabled auto-merge (squash) January 24, 2025 19:48
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts (3)

718-750: Clarify handling of multiple or unsupported transforms in _getOriginalTransformsForLayerOrNull.

This function logs an error and returns null if multiple transforms are present or if the transform type is unsupported. Consider:

  1. Throwing an exception instead of silently returning null, if multiple transforms are truly not supported.
  2. Logging additional context (e.g., dataset ID, layer name) to aid diagnostics.

789-799: Memoization approach in memoizeWithThreeKeys.

Manually managing a MultiKeyMap can be efficient, but watch out for memory usage if it’s storing many large keys. Ensure that the intended key space remains small and that the function is cleared appropriately if needed.


875-878: Refine dataset transform check in hasDatasetTransforms.

The function quickly checks if any layer has transforms. Consider expanding the logging if transforms exist but fail to apply.

frontend/javascripts/oxalis/model_initialization.ts (1)

848-849: Validate necessity of deep cloning
Deep cloning the original dataset settings helps avoid unintended mutations. However, if performance concerns arise, consider whether a shallow clone would suffice—particularly if nested objects within originalDatasetSettings do not need to be deeply copied.

frontend/javascripts/types/api_flow_types.ts (1)

63-71: Redefined CoordinateTransformation type
Switching from a nested matrix to a typed array of Vector4 clarifies dimensional expectations for affine transformations. Verify that all references to CoordinateTransformation in your codebase handle the new union type, including potential migrations from the removed NestedMatrix4.

frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.tsx (2)

1236-1236: Consider passing a full skeleton layer object for clarity.
Currently, an inline object with { category: "skeleton" } is used, which may cause confusion if you need to expand skeleton properties in the future.


766-767: Check lock/unlock icon consistency.
Hovering shows a different icon, which can be intuitive if used intentionally, but consider confirming that the icon states align with the actual locked/unlocked transitions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e33465 and 5cf4876.

📒 Files selected for processing (36)
  • CHANGELOG.unreleased.md (0 hunks)
  • frontend/javascripts/admin/dataset/composition_wizard/04_configure_new_dataset.tsx (1 hunks)
  • frontend/javascripts/dashboard/dataset/dataset_rotation_form_item.tsx (0 hunks)
  • frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx (0 hunks)
  • frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx (0 hunks)
  • frontend/javascripts/dashboard/dataset/dataset_settings_viewconfig_tab.tsx (1 hunks)
  • frontend/javascripts/libs/mjs.ts (0 hunks)
  • frontend/javascripts/oxalis/api/api_latest.ts (1 hunks)
  • frontend/javascripts/oxalis/constants.ts (0 hunks)
  • frontend/javascripts/oxalis/controller/combinations/volume_handlers.ts (2 hunks)
  • frontend/javascripts/oxalis/controller/scene_controller.ts (1 hunks)
  • frontend/javascripts/oxalis/geometries/materials/edge_shader.ts (1 hunks)
  • frontend/javascripts/oxalis/geometries/materials/node_shader.ts (1 hunks)
  • frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts (2 hunks)
  • frontend/javascripts/oxalis/merger_mode.ts (1 hunks)
  • frontend/javascripts/oxalis/model.ts (1 hunks)
  • frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts (3 hunks)
  • frontend/javascripts/oxalis/model/accessors/dataset_layer_transformation_accessor.ts (0 hunks)
  • frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts (3 hunks)
  • frontend/javascripts/oxalis/model/accessors/skeletontracing_accessor.ts (3 hunks)
  • frontend/javascripts/oxalis/model/accessors/tool_accessor.ts (1 hunks)
  • frontend/javascripts/oxalis/model/bucket_data_handling/bounding_box.ts (0 hunks)
  • frontend/javascripts/oxalis/model/bucket_data_handling/layer_rendering_manager.ts (1 hunks)
  • frontend/javascripts/oxalis/model/helpers/nml_helpers.ts (1 hunks)
  • frontend/javascripts/oxalis/model/helpers/transformation_helpers.ts (2 hunks)
  • frontend/javascripts/oxalis/model/reducers/flycam_reducer.ts (1 hunks)
  • frontend/javascripts/oxalis/model/sagas/dataset_saga.ts (1 hunks)
  • frontend/javascripts/oxalis/model/sagas/quick_select_heuristic_saga.ts (1 hunks)
  • frontend/javascripts/oxalis/model_initialization.ts (1 hunks)
  • frontend/javascripts/oxalis/store.ts (1 hunks)
  • frontend/javascripts/oxalis/view/context_menu.tsx (0 hunks)
  • frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.tsx (7 hunks)
  • frontend/javascripts/test/reducers/flycam_reducer.spec.ts (1 hunks)
  • frontend/javascripts/types/api_flow_types.ts (3 hunks)
  • frontend/javascripts/types/globals.d.ts (0 hunks)
  • frontend/javascripts/types/schemas/dataset_view_configuration.schema.ts (0 hunks)
💤 Files with no reviewable changes (11)
  • CHANGELOG.unreleased.md
  • frontend/javascripts/libs/mjs.ts
  • frontend/javascripts/oxalis/constants.ts
  • frontend/javascripts/types/schemas/dataset_view_configuration.schema.ts
  • frontend/javascripts/dashboard/dataset/dataset_settings_data_tab.tsx
  • frontend/javascripts/types/globals.d.ts
  • frontend/javascripts/oxalis/model/bucket_data_handling/bounding_box.ts
  • frontend/javascripts/dashboard/dataset/dataset_rotation_form_item.tsx
  • frontend/javascripts/oxalis/view/context_menu.tsx
  • frontend/javascripts/oxalis/model/accessors/dataset_layer_transformation_accessor.ts
  • frontend/javascripts/dashboard/dataset/dataset_settings_view.tsx
✅ Files skipped from review due to trivial changes (11)
  • frontend/javascripts/oxalis/model/sagas/quick_select_heuristic_saga.ts
  • frontend/javascripts/oxalis/geometries/materials/node_shader.ts
  • frontend/javascripts/oxalis/model/helpers/nml_helpers.ts
  • frontend/javascripts/oxalis/api/api_latest.ts
  • frontend/javascripts/admin/dataset/composition_wizard/04_configure_new_dataset.tsx
  • frontend/javascripts/oxalis/model/accessors/tool_accessor.ts
  • frontend/javascripts/oxalis/merger_mode.ts
  • frontend/javascripts/oxalis/model/bucket_data_handling/layer_rendering_manager.ts
  • frontend/javascripts/dashboard/dataset/dataset_settings_viewconfig_tab.tsx
  • frontend/javascripts/oxalis/geometries/materials/plane_material_factory.ts
  • frontend/javascripts/oxalis/store.ts
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: circleci_build
🔇 Additional comments (37)
frontend/javascripts/test/reducers/flycam_reducer.spec.ts (1)

39-39: Ensure correct usage of M4x4.identity.
If M4x4.identity is a function that returns a new identity matrix, we should call it with parentheses to avoid referencing (and potentially mutating) a single static object. Please verify that referencing M4x4.identity directly is intended.

Run the following script to confirm whether M4x4.identity is a static property or a function within the codebase:

frontend/javascripts/oxalis/model/accessors/flycam_accessor.ts (3)

2-2: Removed unused imports is a good cleanup step.
Since V3 is no longer used, eliminating the redundant import from libs/mjs helps minimize clutter.


23-24: Confirm the correctness of the new import references.
Shifting transformation-related imports to dataset_accessor appears consistent with broader changes. Ensure that the logic in getTransformsForLayer and invertAndTranspose aligns with the new structure (especially if the previous dataset_layer_transformation_accessor code is removed).


197-197: Clarify the usage of M4x4.identity vs. M4x4.identity().
This substitution suggests that M4x4.identity is now a property rather than a function. Verify that it delivers a fresh identity matrix copy each time, rather than a single shared object.

frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts (13)

3-3: Confirm correct usage of new imports for transformations.

This import of M4x4, Matrix4x4, and V3 appears consistent with the rest of the file and seems well-structured for handling transformations and vector operations.


9-15: Ensure consistent usage of newly imported constants and types.

The import statements for IdentityTransform, LongUnitToShortUnitMap, and type Vector3, Vector4, and ViewMode are well-structured. Make sure the usage throughout the file adheres to these validated types and constants.


32-32: New import for APISkeletonLayer is clear.

No issues found. The addition is straightforward and well aligned with the rest of the type imports from the same module.


39-46: Centralize transformation helper imports.

These transformation helper imports are properly co-located. Consider verifying that all transformation logic is consistently defined and consumed from this module to reduce duplication.


752-788: Check for edge cases around native rendering in _getTransformsForLayerOrNull.

This function inverts transforms when another layer is “native.” Verify:

  1. Behavior when nativelyRenderedLayerName does not exist in the dataset.
  2. Potential risk of returning null transforms if the native layer is invalid.

801-811: Fallback to IdentityTransform enhances robustness.

Returning the IdentityTransform when no transform is found protects against null references. Implementation is concise and consistent.


813-834: Skeleton layer handling in _getTransformsForSkeletonLayerOrNull.

This approach aligns skeleton transforms with the logic in _getOriginalTransformsForLayerOrNull. Confirm that future skeleton-specific transforms (e.g., partial transforms) won’t trigger unexpected null returns.


836-847: Memoization for getTransformsForSkeletonLayerOrNull.

Implementation is consistent with the pattern above. Confirm that any dynamic changes to skeleton transforms are handled properly if the memoized result becomes stale.


848-860: Constructing transforms per layer in _getTransformsPerLayer.

The iteration that assigns transforms for each layer is straightforward. Make sure performance is acceptable on datasets with large layer counts.


862-863: Memoized export for getTransformsPerLayer.

No issues. This is consistent with prior memoization usage.


864-873: Inline transform usage in getInverseSegmentationTransformer.

Returning a specialized transform function is flexible. Verify that the unscaled transform usage is always correct for segmentation.


880-887: Flattened-to-nested matrix conversion with flatToNestedMatrix.

Straightforward partitioning of the 16-element array into 4x4 vectors. Implementation is concise and appears correct.


889-899: Preserve GPU compatibility in invertAndTranspose.

The memoized function satisfies common transformation usage for rendering. Confirm that all relevant usage sites respect the difference between math libraries that expect row-major vs. column-major ordering.

frontend/javascripts/oxalis/controller/combinations/volume_handlers.ts (2)

59-62: Validate direct usage of globalPos in getSegmentIdForPosition.

The function no longer applies layer-specific transforms to the incoming position. Confirm that skipping transforms is intentional and that it won’t break segmentation logic for layers with custom transforms.


84-94: Confirm correct async bucket loading in getSegmentIdForPositionAsync.

  1. Ensuring the newly retrieved zoom step and data are suitable for untransformed globalPos.
  2. Validate queries on multi-transformed datasets or skeleton layers.
frontend/javascripts/oxalis/geometries/materials/edge_shader.ts (1)

6-6: Updated import of getTransformsForSkeletonLayer.

The function is now centralized in dataset_accessor, which simplifies code organization. Make sure the new import path references the same transform logic to avoid unexpected discrepancies.

frontend/javascripts/oxalis/model/helpers/transformation_helpers.ts (3)

7-7: Function signature matches newly introduced Vector4-based structure.
Using a typed 4-element array of Vector4 for flattening improves clarity by exposing each row vector. This approach seems maintainable and consistent with the rest of the transform-related refactoring.


29-31: Align affine transform creation with the new matrix flattening logic.
The refactored function properly leverages nestedToFlatMatrix for consistency. Confirm no downline code still depends on the old nested matrix format.

✅ Verification successful

Matrix transformation system is properly aligned
The implementation correctly uses nestedToFlatMatrix and is part of a well-structured, type-safe transformation system. All matrix format conversions are consistent throughout the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Ensure no calls are left that pass a NestedMatrix4 to createAffineTransformFromMatrix
rg 'createAffineTransformFromMatrix\s*\(' -A 2

Length of output: 731


Script:

#!/bin/bash
# Check implementation and context
echo "=== Implementation of createAffineTransformFromMatrix ==="
ast-grep --pattern 'export function createAffineTransformFromMatrix($_) {
  $$$
}'

echo -e "\n=== Context of usage in dataset_accessor.ts ==="
rg -B 5 -A 5 'createAffineTransformFromMatrix' frontend/javascripts/oxalis/model/accessors/dataset_accessor.ts

echo -e "\n=== Related matrix transformation utilities ==="
rg 'nestedToFlatMatrix|flatToNestedMatrix' -A 2

Length of output: 3740


5-5: Ensure references to Vector4 are consistently updated across codebase.
Replacing NestedMatrix4 with [Vector4, Vector4, Vector4, Vector4] is logical as it consolidates matrix handling under a single approach. Verify all references and type exports are updated to avoid errors in files that previously relied on NestedMatrix4.

✅ Verification successful

Vector4 type usage is consistent across codebase
The migration from NestedMatrix4 to [Vector4, Vector4, Vector4, Vector4] is complete and consistent. All matrix-related operations use the new type pattern uniformly, with no remaining references to the old type.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Script to find any references to 'NestedMatrix4' across the project and ensure they are removed or replaced properly
rg 'NestedMatrix4' -A 3 -B 3

Length of output: 28


Script:

#!/bin/bash
# Search for Vector4 type references and matrix-related types
echo "=== Vector4 References ==="
rg "Vector4" -t typescript -A 2 -B 2

echo -e "\n=== Matrix-Related Type Definitions ==="
ast-grep --pattern 'type $_ = [Vector4, Vector4, Vector4, Vector4]'

echo -e "\n=== Type Exports with Vector4 ==="
rg "export.*Vector4" -t typescript

Length of output: 454


Script:

#!/bin/bash
# Search for Vector4 references in frontend directory
echo "=== Vector4 References ==="
rg "Vector4" ./frontend -A 2 -B 2

echo -e "\n=== Constants File Check ==="
fd -e ts -e tsx constants.ts -x cat {} 

echo -e "\n=== Matrix Type Patterns ==="
rg "\[Vector4,\s*Vector4,\s*Vector4,\s*Vector4\]" ./frontend

Length of output: 59518

frontend/javascripts/oxalis/model/sagas/dataset_saga.ts (1)

18-19: Reinstating isLayerVisible usage.
Re-adding isLayerVisible from dataset_accessor clarifies the layer visibility check. Confirm that usage is correct in the offsets where it’s called to ensure we don’t replicate any previous logic issues.

frontend/javascripts/oxalis/model/accessors/skeletontracing_accessor.ts (4)

29-30: Importing newly consolidated transformation logic.
Replacing older transformation imports with getTransformsForSkeletonLayer and getTransformsForSkeletonLayerOrNull is consistent with your refactoring strategy. Ensure old calls aren’t left in the code.


221-221: Use of getTransformsForSkeletonLayerOrNull.
This succinctly checks for skeleton-layer transformations. Double-check edge cases where the layer might not exist or be invalid.


234-235: Explicit assignment of nativelyRenderedLayerName.
Storing the name in a local variable helps keep code readable and consistent with usage in the following lines. Just ensure no concurrency issues arise from referencing updated states.


242-243: Reuse local variable for nativelyRenderedLayerName.
Similar logic to lines 234-235. Maintaining consistent usage avoids confusion. Ensure any changes to state.datasetConfiguration are properly accounted for before reusing.

frontend/javascripts/oxalis/model.ts (1)

227-228: Directly retrieving additionalCoordinates for segment ID lookup.
By cutting out extraneous coordinate transformations, the approach is simplified. Watch for potential mismatch if other code still expects transformed coordinates.

frontend/javascripts/oxalis/model_initialization.ts (1)

845-845: Preserving the original dataset settings when annotation is absent
This return statement effectively reverts to using the unmodified dataset settings in scenarios without an annotation. This is consistent with the goal of removing rotation-specific logic.

frontend/javascripts/types/api_flow_types.ts (2)

10-10: New Vector4 import aligns with 4×4 matrix representation
The addition of Vector4 supports the new affine matrix structure. Ensure all code referencing 4×4 transformations consistently uses Vector4 to maintain type safety.


97-98: Simplified APISkeletonLayer
Removing the name property from APISkeletonLayer makes its interface more concise. If any references to APISkeletonLayer.name remain, ensure they are also updated.

frontend/javascripts/oxalis/controller/scene_controller.ts (1)

35-35: Refactored import for getTransformsForLayerOrNull
Importing getTransformsForLayerOrNull from dataset_accessor rather than the deprecated dataset_layer_transformation_accessor indicates proper alignment with new transformation handling. Confirm that all references to the old module have been removed.

frontend/javascripts/oxalis/view/left-border-tabs/layer_settings_tab.tsx (4)

57-59: Imports look good.
The usage of getWidestMags and hasDatasetTransforms is valid and consistent with the rest of the code.


60-60: Import usage confirmed.
getMaxZoomValueForMag and getPosition are used correctly and help keep the code structured.


84-87: No issues with the transformation helpers import.
The logic for invertTransform and transformPointUnscaled appears consistent and properly integrated.


1186-1186: LGTM on destructuring showSkeletons.
This ensures clarity in referencing the skeleton's display state.

const position = [matrix[12], matrix[13], matrix[14]];
// Reset rotation
const newMatrix = rotateOnAxis(M4x4.scale(scale, M4x4.identity(), []), Math.PI, [0, 0, 1]);
const newMatrix = rotateOnAxis(M4x4.scale(scale, M4x4.identity, []), Math.PI, [0, 0, 1]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Prevent unintended mutation of the identity matrix.
If M4x4.identity is not returning a fresh matrix instance on each reference, scaling or rotating it might unintentionally affect other parts of the code reusing the same matrix object. Consider calling it as a function (if it indeed is one) or cloning, to ensure a unique identity matrix is obtained:

-const newMatrix = rotateOnAxis(M4x4.scale(scale, M4x4.identity, []), Math.PI, [0, 0, 1]);
+const newMatrix = rotateOnAxis(M4x4.scale(scale, M4x4.identity(), []), Math.PI, [0, 0, 1]);

Committable suggestion skipped: line range outside the PR's diff.

@MichaelBuessemeyer MichaelBuessemeyer merged commit e20c218 into master Jan 24, 2025
3 checks passed
@MichaelBuessemeyer MichaelBuessemeyer deleted the revert-8159-allow-perma-dataset-rotation branch January 24, 2025 19:57
@coderabbitai coderabbitai bot mentioned this pull request Jun 2, 2025
46 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants