Fold Demo#
Demonstration of Fold services in Dips Python API.
This script demonstrates IFoldServices methods including: - AddFoldWindow: Create a new fold window - GetFoldList: List all folds - DeleteFold: Remove a fold
Code Snippet: FoldDemo.py#
"""
Demonstration of Fold services in Dips Python API.
This script demonstrates IFoldServices methods including:
- AddFoldWindow: Create a new fold window
- GetFoldList: List all folds
- DeleteFold: Remove a fold
FoldWindowEntityInfo Structure:
- color: Display color
- wrapped_freehand_fold_window: WrappedFreehandWindow containing:
- id: Unique identifier
- primary_window: FreehandWindow with polygon points
- secondary_window: Optional FreehandWindow (for wrapped windows)
"""
import math
from dips import DipsApp
from dips import DipsAPI_pb2
import dips.FoldWindowEntityInfoVal
import dips.WrappedFreehandWindowVal
import dips.FreehandWindowVal
import dips.TrendPlungeVal
import dips.AngleDataVal
import dips.ColorSurrogateVal
# =============================================================================
# HELPER FUNCTIONS
# =============================================================================
def create_trend_plunge(trend_deg: float, plunge_deg: float):
"""Create a TrendPlunge from degrees."""
tp = dips.TrendPlungeVal.TrendPlungeVal()
tp.trend = dips.AngleDataVal.AngleDataVal()
tp.trend.angle_radians = math.radians(trend_deg)
tp.plunge = dips.AngleDataVal.AngleDataVal()
tp.plunge.angle_radians = math.radians(plunge_deg)
return tp
def create_color(r: int, g: int, b: int, a: int = 255):
"""Create a Color from RGBA values."""
color = dips.ColorSurrogateVal.ColorSurrogateVal()
color.r = r
color.g = g
color.b = b
color.a = a
return color
def create_freehand_window(polygon_points):
"""Create a FreehandWindow from a list of (trend, plunge) tuples."""
window = dips.FreehandWindowVal.FreehandWindowVal()
# Use append() for protobuf list fields instead of direct assignment
for t, p in polygon_points:
window.polygon.append(create_trend_plunge(t, p))
window.is_wrapped = False
return window
def create_empty_freehand_window():
"""Create an empty FreehandWindow (for secondary window when not wrapped)."""
window = dips.FreehandWindowVal.FreehandWindowVal()
window.is_wrapped = False
return window
def create_fold_window(fold_id: str, color_tuple, polygon_points):
"""Create a FoldWindowEntityInfo with the given parameters."""
# Create the freehand window with polygon points
primary = create_freehand_window(polygon_points)
# Create an empty secondary window (required by the API even if not wrapped)
secondary = create_empty_freehand_window()
# Create the wrapped freehand window
wrapped = dips.WrappedFreehandWindowVal.WrappedFreehandWindowVal()
wrapped.id = fold_id
wrapped.primary_window = primary
wrapped.secondary_window = secondary
# Create the fold window entity info
fold_info = dips.FoldWindowEntityInfoVal.FoldWindowEntityInfoVal()
fold_info.color = create_color(*color_tuple)
fold_info.wrapped_freehand_fold_window = wrapped
return fold_info
# =============================================================================
# FOLD DEMONSTRATIONS
# =============================================================================
def demonstrate_add_fold_window(model):
"""Demonstrate adding a fold window."""
print("\n" + "=" * 60)
print("ADD FOLD WINDOW")
print("=" * 60)
try:
# Define a triangular fold window region
# Points define a polygon on the stereonet (trend/plunge pairs)
polygon_points = [
(40, 20), # Point 1
(50, 30), # Point 2
(45, 40), # Point 3
(35, 30), # Point 4
]
fold_info = create_fold_window(
fold_id="DemoFold",
color_tuple=(255, 100, 0), # Orange
polygon_points=polygon_points
)
result = model.AddFoldWindow(fold_info)
print(f" ✓ AddFoldWindow: 'DemoFold'")
print(f" Polygon with {len(polygon_points)} vertices")
return result
except Exception as e:
print(f" ✗ AddFoldWindow: {e}")
return None
def demonstrate_get_fold_list(model):
"""Demonstrate listing all folds."""
print("\n" + "=" * 60)
print("GET FOLD LIST")
print("=" * 60)
try:
folds = model.GetFoldList()
print(f" ✓ GetFoldList: {len(folds)} fold(s) found")
for i, fold_ref in enumerate(folds):
fold_value = fold_ref.GetValue()
print(f" [{i+1}] ID: '{fold_value.id}'")
return folds
except Exception as e:
print(f" ✗ GetFoldList: {e}")
return []
def demonstrate_delete_fold(model, fold_ref):
"""Demonstrate deleting a fold."""
print("\n" + "=" * 60)
print("DELETE FOLD")
print("=" * 60)
if fold_ref is None:
print(" - DeleteFold: No fold to delete")
return
try:
fold_value = fold_ref.GetValue()
fold_id = fold_value.id
model.DeleteFold(fold_ref)
print(f" ✓ DeleteFold: '{fold_id}'")
except Exception as e:
print(f" ✗ DeleteFold: {e}")
def demonstrate_multiple_folds(model):
"""Demonstrate creating multiple fold windows."""
print("\n" + "=" * 60)
print("MULTIPLE FOLD EXAMPLES")
print("=" * 60)
# Each fold has: (id, color_rgb, list of (trend, plunge) polygon points)
fold_examples = [
("NE Fold Region", (255, 0, 0), [
(30, 15), (60, 15), (60, 35), (30, 35) # Rectangular region in NE
]),
("NW Fold Region", (0, 255, 0), [
(300, 20), (330, 20), (330, 40), (300, 40) # Rectangular region in NW
]),
("E Fold Region", (0, 0, 255), [
(80, 10), (100, 10), (100, 30), (80, 30) # Rectangular region in E
]),
]
created_folds = []
for fold_id, color_rgb, polygon_points in fold_examples:
try:
fold_info = create_fold_window(fold_id, color_rgb, polygon_points)
result = model.AddFoldWindow(fold_info)
created_folds.append(result)
print(f" ✓ Created: '{fold_id}' ({len(polygon_points)} vertices)")
except Exception as e:
print(f" ✗ Failed to create '{fold_id}': {e}")
return created_folds
def demonstrate_cleanup(model, folds_to_delete):
"""Clean up created folds."""
print("\n" + "=" * 60)
print("CLEANUP")
print("=" * 60)
for fold_ref in folds_to_delete:
try:
fold_value = fold_ref.GetValue()
model.DeleteFold(fold_ref)
print(f" ✓ Deleted: '{fold_value.id}'")
except Exception as e:
print(f" ✗ Delete failed: {e}")
# =============================================================================
# MAIN
# =============================================================================
def main():
"""Main demonstration function."""
print("=" * 60)
print("Dips API - Fold Services Demo")
print("=" * 60)
# Connect to Dips
print("\nConnecting to Dips application...")
try:
app = DipsApp.LaunchApp(62535)
print("✓ Connected to Dips")
except Exception as e:
print(f"✗ Failed to connect: {e}")
print("Make sure Dips is running with scripting enabled on port 62535")
return
model = app.GetModel()
# Show initial state
print("\n" + "-" * 60)
print("INITIAL STATE")
print("-" * 60)
demonstrate_get_fold_list(model)
# Add a single fold
new_fold = demonstrate_add_fold_window(model)
# List folds again
demonstrate_get_fold_list(model)
# Delete the fold
demonstrate_delete_fold(model, new_fold)
# Create multiple folds
created_folds = demonstrate_multiple_folds(model)
# List all folds
demonstrate_get_fold_list(model)
# Cleanup (commented out to keep folds visible)
# demonstrate_cleanup(model, created_folds)
# Show final state
print("\n" + "-" * 60)
print("FINAL STATE")
print("-" * 60)
demonstrate_get_fold_list(model)
# Show the application
app.Show()
# Summary
print("\n" + "=" * 60)
print("DEMONSTRATION COMPLETE")
print("=" * 60)
print("""
Fold services demonstrated (3 methods):
- AddFoldWindow: Create a new fold window with polygon vertices
- GetFoldList: List all folds in the project
- DeleteFold: Remove a fold from the project
FoldWindowEntityInfo Structure:
- color: Display color for the fold window
- wrapped_freehand_fold_window: WrappedFreehandWindow containing:
- id: Unique identifier for the fold
- primary_window: FreehandWindow with polygon points
- secondary_window: Optional (for windows that wrap around)
FreehandWindow Structure:
- polygon: List of TrendPlunge points defining the window boundary
- is_wrapped: Whether the window wraps around the stereonet edge
Note: Fold windows are defined by polygon regions on the stereonet,
similar to freehand set windows. The polygon vertices are specified
as trend/plunge pairs.
""")
if __name__ == "__main__":
main()