Measurement Operations
Measurement Operations Tutorial.
This tutorial demonstrates operations on 3D measurements including creation, querying values, appearance settings, import/export, and snapping.
Prerequisites
- Volvicon application must be running
- For snapping operations, surfaces or masks must be present
Listing Measurements​
all_measurements = app.get_all_measurement_names()
all_surfaces = app.get_all_surface_names()
all_masks = app.get_all_mask_names()
print(f"Available measurements: {all_measurements}")
# Get measurements by type
# point_measurements = measurement_operations.get_measurement_names_by_type(api.MeasurementType.Point)
# distance_measurements = measurement_operations.get_measurement_names_by_type(api.MeasurementType.Distance)
# angle_measurements = measurement_operations.get_measurement_names_by_type(api.MeasurementType.Angle)
Importing and Exporting Measurements​
# Import measurements from file
# success = measurement_operations.import_measurements_settings_from_disk(r'C:\data\measurements.ini', False) # deleteExisting=False (bool)
# Export all measurements to file
# success = measurement_operations.export_measurements_settings_to_disk(r'C:\output\measurements.ini')
# Export specific measurements to file
# success = measurement_operations.export_measurements_to_disk(['Point 001', 'Distance 001'], r'C:\output\selected.json')
Creating Measurements​
# Create a point measurement
# point_name = measurement_operations.create_point(
# [10.0, 20.0, 30.0], # position [x, y, z]
# "MyPoint" # name (str, optional)
# )
# Create a distance measurement
# distance_name = measurement_operations.create_distance(
# [0.0, 0.0, 0.0], # point1 [x, y, z]
# [100.0, 50.0, 25.0], # point2 [x, y, z]
# "MyDistance" # name (str, optional)
# )
# Create an angle measurement
# angle_name = measurement_operations.create_angle(
# [0.0, 0.0, 0.0], # point1 [x, y, z]
# [50.0, 0.0, 0.0], # vertex [x, y, z]
# [50.0, 50.0, 0.0], # point3 [x, y, z]
# "MyAngle" # name (str, optional)
# )
# Create a contour measurement
# contour_name = measurement_operations.create_contour(
# [[0.0, 0.0, 0.0], [100.0, 0.0, 0.0], [100.0, 100.0, 0.0], [0.0, 100.0, 0.0]], # points (list of [x,y,z])
# True, # closedLoop (bool)
# "MyContour" # name (str, optional)
# )
# Create a caption (text annotation)
# annotation_name = measurement_operations.create_annotation(
# [50.0, 50.0, 50.0], # position [x, y, z]
# "Sample annotation", # text (str)
# "MyAnnotation" # name (str, optional)
# )
# Create a diameter measurement (three points define diameter endpoints and a third point)
# diameter_name = measurement_operations.create_diameter(
# [0.0, 0.0, 0.0], # point1 [x, y, z]
# [100.0, 0.0, 0.0], # point2 [x, y, z]
# [50.0, 50.0, 0.0], # point3 [x, y, z]
# "MyDiameter" # name (str, optional)
# )
# Create a circle measurement using center and a boundary point
# circle_name = measurement_operations.create_circle(
# [0.0, 0.0, 0.0], # center [x, y, z]
# [10.0, 0.0, 0.0], # a point on circumference
# "MyCircle"
# )
# Create an ellipse measurement using center and two axis-defining points
# ellipse_name = measurement_operations.create_ellipse(
# [0.0, 0.0, 0.0], # center [x, y, z]
# [10.0, 0.0, 0.0], # first axis point
# [0.0, 5.0, 0.0], # second axis point
# "MyEllipse"
# )
# Create a rectangle measurement using center and two extent points
# rectangle_name = measurement_operations.create_rectangle(
# [0.0, 0.0, 0.0], # center [x, y, z]
# [10.0, 0.0, 0.0], # second point
# [0.0, 5.0, 0.0], # third point
# "MyRectangle"
# )
# Create a box measurement (center-based)
# box_name = measurement_operations.create_box(
# [50.0, 50.0, 50.0], # center [x, y, z]
# "MyBox"
# )
Querying Measurement Values​
# if all_measurements:
# # Get measurement type
# measurement_type = measurement_operations.get_measurement_type(all_measurements[0])
# print(f"Type: {measurement_type}")
#
# # Get formatted measurement value string (e.g., "12.5 mm")
# value_str = measurement_operations.get_measurement_value_string(all_measurements[0])
# print(f"Value: \n{value_str}")
#
# # Get measurement data (name, visibility, locked status, points)
# data : api.MeasurementData = measurement_operations.get_measurement_data(all_measurements[0])
# print(f"Name: {data.name}, Visible: {data.visible}, Locked: {data.locked}")
# print(f"Points: {data.points}")
#
# # Get point coordinates
# points = measurement_operations.get_points(all_measurements[0])
# print(f"Points: {points}")
Querying Specific Measurement Types​
# point_measurement : api.PointMeasurement = measurement_operations.get_point_measurement("Point 001")
# print(f"Position: {point_measurement.position}, Gray value: {point_measurement.gray_value}")
# distance_measurement : api.DistanceMeasurement = measurement_operations.get_distance_measurement("Distance 003")
# print(f"Point1: {distance_measurement.point1}, Point2: {distance_measurement.point2}")
# print(f"Distance: {distance_measurement.distance} mm")
# angle_measurement : api.AngleMeasurement = measurement_operations.get_angle_measurement("Angle 005")
# print(f"Point1: {angle_measurement.point1}, Center: {angle_measurement.center}, Point2: {angle_measurement.point2}")
# print(f"Angle: {angle_measurement.angle} degrees")
# diameter_measurement : api.DiameterMeasurement = measurement_operations.get_diameter_measurement("Diameter 007")
# print(f"Diameter: {diameter_measurement.diameter}, Centroid: {diameter_measurement.centroid}")
# contour_measurement : api.ContourMeasurement = measurement_operations.get_contour_measurement("Contour 008")
# print(f"Area: {contour_measurement.area}, Perimeter: {contour_measurement.perimeter}")
# print(f"Centroid: {contour_measurement.centroid}, Max distance: {contour_measurement.max_distance_through_centroid}")
# circle_measurement : api.CircleMeasurement = measurement_operations.get_circle_measurement("Circle 016")
# print(f"Diameter: {circle_measurement.diameter}, Centroid: {circle_measurement.centroid}")
# ellipse_measurement : api.EllipseMeasurement = measurement_operations.get_ellipse_measurement("Ellipse 017")
# print(f"D1: {ellipse_measurement.d1}, D2: {ellipse_measurement.d2}")
# print(f"Area: {ellipse_measurement.area}, Perimeter: {ellipse_measurement.perimeter}")
# print(f"Eccentricity: {ellipse_measurement.eccentricity}, Centroid: {ellipse_measurement.centroid}")
# rectangle_measurement : api.RectangleMeasurement = measurement_operations.get_rectangle_measurement("Rectangle 018")
# print(f"Width: {rectangle_measurement.width}, Height: {rectangle_measurement.height}")
# print(f"Area: {rectangle_measurement.area}, Perimeter: {rectangle_measurement.perimeter}")
# box_measurement : api.BoxMeasurement = measurement_operations.get_box_measurement("Box 019")
# print(f"Width: {box_measurement.width}, Height: {box_measurement.height}, Depth: {box_measurement.depth}")
# print(f"Volume: {box_measurement.volume}, Perimeter: {box_measurement.perimeter}")
# annotation_measurement : api.AnnotationMeasurement = measurement_operations.get_annotation_measurement("Text Annotation 009")
# print(f"Position: {annotation_measurement.position}, Gray value: {annotation_measurement.gray_value}")
Annotation Text Helpers​
# annotation_name = measurement_operations.create_annotation(
# [50.0, 50.0, 50.0],
# "Initial annotation text",
# "Annotation For Text Update"
# )
#
# # Set custom annotation text for an annotation measurement
# measurement_operations.set_annotation_measurement_text(annotation_name, "Updated text from script")
#
# # Read the current annotation text back
# current_text = measurement_operations.get_annotation_measurement_text(annotation_name)
# print(f"Current annotation text: {current_text}")
#
# # Passing an empty string switches the annotation back to image info at the anchor point
# measurement_operations.set_annotation_measurement_text(annotation_name, "")
Modifying Measurements​
# if all_measurements:
# # Set measurement points
# measurement_operations.set_points(all_measurements[0], [[10.0, 20.0, 30.0]])
#
# # Apply transformation matrix
# # matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 10,20,30,1] # Translation example
# # measurement_operations.transform([all_measurements[0]], matrix)
#
# # Lock/unlock measurement (locked cannot be moved interactively)
# measurement_operations.set_lock([all_measurements[0]], True) # Lock
# measurement_operations.set_lock([all_measurements[0]], False) # Unlock
#
# # Set active measurement for editing
# measurement_operations.set_active(all_measurements[0])
Measurement Properties Dialog Round-Trip​
# if all_measurements:
# props : api.MeasurementProperties = measurement_operations.get_measurement_properties(all_measurements[0])
# print(f"Description: {props.description}")
# print(f"Text size: {props.text_size}, Point scale factor: {props.point_scale_factor}")
#
# # Common properties available on most measurement types
# props.description = "Updated from the scripting tutorial"
# props.annotation_background_color = [0.05, 0.05, 0.05]
# props.annotation_background_opacity = 0.35
# props.text_size = 18
# props.text_bold = True
# props.text_italic = False
# props.text_color = [1.0, 0.95, 0.75]
# props.text_opacity = 1.0
# props.point_scale_factor = 6.0
# props.point_color = [0.0, 1.0, 0.0]
# props.point_opacity = 1.0
# props.line_width = 2.5
# props.line_color = [1.0, 0.3, 0.2]
# props.line_opacity = 0.9
# props.follow_object_profile_enabled = True # Ignored for box measurements
#
# measurement_operations.set_measurement_properties(all_measurements[0], props)
#
# # Annotation measurement specific properties
# # if annotation_name:
# # measurement_properties : api.MeasurementProperties = measurement_operations.get_measurement_properties(annotation_name)
# # measurement_properties.display_image_info_at_anchor_point = False
# # measurement_properties.annotation_text = "User-defined caption text"
# # measurement_operations.set_measurement_properties(annotation_name, measurement_properties)
#
# # Contour measurement specific properties
# # if contour_name:
# # measurement_properties : api.MeasurementProperties = measurement_operations.get_measurement_properties(contour_name)
# # measurement_properties.closed_loop = True
# # measurement_properties.maximum_curve_line_segments = 12
# # measurement_properties.add_intermediate_node_on_contour = True # Best used when curve segments >= 7
# # measurement_operations.set_measurement_properties(contour_name, measurement_properties)
Snapping to Objects​
# if all_measurements and all_surfaces:
# # Snap measurement points to nearest surface
# measurement_operations.snap_to_surface([all_measurements[0]], all_surfaces[0])
# if all_measurements and all_masks:
# # Snap measurement points to nearest mask surface
# measurement_operations.snap_to_mask([all_measurements[0]], all_masks[0])
Appearance Settings​
# if all_measurements:
# # Set color (RGB values 0.0-1.0)
# measurement_operations.set_color([all_measurements[0]], [1.0, 0.0, 0.0]) # Red
#
# # Set opacity (0.0-1.0)
# measurement_operations.set_opacity([all_measurements[0]], 0.8)
#
# # Set line width
# measurement_operations.set_line_width([all_measurements[0]], 2.0)
#
# # Set end point (handle) color
# measurement_operations.set_end_point_color([all_measurements[0]], [0.0, 1.0, 0.0]) # Green
#
# # Set end point (handle) size factor
# measurement_operations.set_end_point_size_factor([all_measurements[0]], 1.5)
Annotation Settings​
# if all_measurements:
# # Set annotation visibility
# measurement_operations.set_annotation_visibility([all_measurements[0]], True)
#
# # Set annotation type
# measurement_operations.set_annotation_type(
# [all_measurements[0]],
# api.MeasurementAnnotationType.NameAndValue # Name, Value, NameAndValue, Position, NameAndPosition, NotAny
# )
#
# # Set annotation background color
# measurement_operations.set_annotation_background_color([all_measurements[0]], [0.0, 0.0, 0.0]) # Black
#
# # Set annotation background opacity
# measurement_operations.set_annotation_background_opacity([all_measurements[0]], 0.5)
#
# # Show annotation only on active measurement
# measurement_operations.set_annotation_visibility_on_active_only()
Visibility Settings​
# if all_measurements:
# # Set 3D axes visibility
# measurement_operations.set_3d_axes_visibility([all_measurements[0]], True)
#
# # Show 3D axes only on active measurement
# measurement_operations.set_3d_axes_visibility_on_active_only()
#
# # Set 2D cross visibility in slice views
# measurement_operations.set_2d_cross_visibility([all_measurements[0]], True)
#
# # Set handle visibility
# measurement_operations.set_handle_visibility([all_measurements[0]], True)
#
# # Set slice views visibility
# measurement_operations.set_slice_views_visibility([all_measurements[0]], True)
Always Show Mode​
# Enable "always show" mode (measurements visible even when markup tool inactive)
# measurement_operations.set_always_show(True)
# Check if always show is enabled
# is_always_show = measurement_operations.is_always_show_enabled()
# print(f"Always show enabled: {is_always_show}")
# Hide/show based on always show flag
# measurement_operations.hide_based_on_always_show_flag(True) # Hide
# measurement_operations.hide_based_on_always_show_flag(False) # Restore
print("Measurement operations tutorial completed successfully.")
Related Resources​
- API Reference - API documentation
- Quick Reference - Common methods at a glance