Skip to content

Commit

Permalink
ADD: w_solver, wip w_dataset_closest_lines_insertion
Browse files Browse the repository at this point in the history
  • Loading branch information
petrasvestartas committed Oct 9, 2024
1 parent 50aff4d commit 1502948
Show file tree
Hide file tree
Showing 9 changed files with 531 additions and 117 deletions.
4 changes: 2 additions & 2 deletions src/rhino/plugin/commands/w_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import Rhino
import System
import System.IO
import compas_wood
from compas_wood.binding import read_xml_polylines
import os
from wood_rui import add_polylines, wood_rui_globals, BooleanForm
Expand Down Expand Up @@ -59,7 +58,7 @@ def load_data_set(path: str = "C://brg//2_code//compas_wood//src//rhino//plugin/
"""

# Get filenames from the path:
module_path: str = path#os.path.dirname(compas_wood.__file__)
module_path: str = path # os.path.dirname(compas_wood.__file__)
print("Data-sets are located in the shared folder:\n" + module_path)
foldername: str = module_path + os.sep
files: List[str] = os.listdir(foldername)
Expand All @@ -78,6 +77,7 @@ def load_data_set(path: str = "C://brg//2_code//compas_wood//src//rhino//plugin/
polylines = read_xml_polylines(foldername, value[0])
wood_rui_globals[value[0]]["polylines"] = polylines
add_polylines(polylines, value[0])
Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw() # 0 ms

return file_names_without_extensions

Expand Down
175 changes: 175 additions & 0 deletions src/rhino/plugin/commands/w_dataset_closest_lines_insertion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import Rhino
import Rhino.Input
import Rhino.DocObjects
from typing import *
from wood_rui import wood_rui_globals

def find_insertion_lines():
###############################################################################
# Run the closest point search
###############################################################################

# convert element polylines to a flattened dictionary:
segments_dictionary = {}
# stores ids e.g. int , [element_int,bottom_or_top_polyline_int,edge,int, bounding_box, hit_count, point_id]
vectors = []
count = 0
for i in range(len(polylines)):
vectors.append([Vector3d.Zero] * (polylines[i][0].SegmentCount + 2))
for j in range(len(polylines[i])):
for k in range(polylines[i][j].SegmentCount):
bbox = polylines[i][j].SegmentAt(k).BoundingBox
bbox.Inflate(0.02)
segments_dictionary[count] = [i, j, k, bbox, polylines[i][j].SegmentAt(k)]

count = count + 1

# create a tree
rtree = Rhino.Geometry.RTree()

# fill the tree
for i in segments_dictionary:
rtree.Insert(segments_dictionary[i][3], i)

# call_backs of rtree search
def search_callback(sender, rtree_event_args):
data_by_reference.append(rtree_event_args.Id)

# perform search, two times first for start points of a polyline, second for the end point
for i in range(len(lines)):
data_by_reference = []
if rtree.Search(Sphere(lines[i].From, 0), search_callback, data_by_reference):
for j in data_by_reference:
if (
lines[i].From.DistanceToSquared(segments_dictionary[j][4].ClosestPoint(lines[i].From, True))
< 0.001
):
vectors[segments_dictionary[j][0]][segments_dictionary[j][2] + 2] = lines[i].Direction
# vectors[segments_dictionary[j][0]][segments_dictionary[j][2]+2].Unitize()

for i in range(len(lines)):
data_by_reference = []
if rtree.Search(Sphere(lines[i].To, 0), search_callback, data_by_reference):
for j in data_by_reference:
if lines[i].To.DistanceToSquared(segments_dictionary[j][4].ClosestPoint(lines[i].To, True)) < 0.001:
vectors[segments_dictionary[j][0]][segments_dictionary[j][2] + 2] = -lines[i].Direction
# vectors[segments_dictionary[j][0]][segments_dictionary[j][2]+2].Unitize()

###############################################################################
# Output
###############################################################################
_polylines_out = polylines_out
_vectors = th.list_to_tree(vectors)

# return outputs if you have them; here I try it for you:
return (_polylines_out, _vectors)


def command_line_input() -> Tuple[str, List[Rhino.Geometry.Line]]:

# Create an instance of GetOption to define options in one line
get_options: Rhino.Input.Custom.GetOption = Rhino.Input.Custom.GetOption()

# Populate options from wood_rui_globals.datasets.keys()

case_names = list(wood_rui_globals.dataset.keys())

# Check if case_names is empty
if not case_names:
Rhino.RhinoApp.WriteLine("\nATTENTION: First create geometry, set joint parameters, and then run the solver.\n")
return Rhino.Commands.Result.Cancel # Exit if no datasets are found

# Add an option to select lines
get_options.AddOption("select_lines")

# Add case names as options
for case_name in case_names:
get_options.AddOption(case_name)

Rhino.RhinoApp.WriteLine("\n─ Select a case and lines. Hit 'Enter' when done. ─")
get_options.SetCommandPrompt("Select a case or lines.")

# Initialize storage for the case name and selected lines
selected_case_name = None
selected_lines = []

# Run the option selection loop
while True:
res = get_options.Get()

# Check if the operation was cancelled or Enter was pressed (GetResult.Nothing)
if res == Rhino.Input.GetResult.Nothing or res == Rhino.Input.GetResult.Cancel:
if not selected_case_name:
selected_case_name = case_names[0] # Default to the first case if none was selected
Rhino.RhinoApp.WriteLine("Selection completed.")
break

# If an option is selected
if res == Rhino.Input.GetResult.Option:
option_name = get_options.Option().EnglishName

# If user selects the option to choose lines
if option_name == "select_lines":
Rhino.RhinoApp.WriteLine("\n─ Select the lines. Press Enter when done. ─")

# Create an instance of GetObject to select curves (lines)
go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select lines")
go.GeometryFilter = Rhino.DocObjects.ObjectType.Curve # Filter only curves (includes lines)
go.SubObjectSelect = False # Don't allow subobject selection
go.EnablePreSelect(True, True) # Allow pre-selection of objects
go.GetMultiple(1, 0) # Allow selecting multiple lines, 1 as the minimum

# Check the result of the line selection
if go.CommandResult() != Rhino.Commands.Result.Success:
Rhino.RhinoApp.WriteLine("Failed to select lines.")
continue # Continue to let user select more lines

# Process the selected lines
for i in range(go.ObjectCount):
obj_ref = go.Object(i)
curve = obj_ref.Curve()
if curve:
selected_lines.append(curve)

Rhino.RhinoApp.WriteLine(f"Total lines selected: {len(selected_lines)}")

# If the user selects a case
elif option_name in case_names:
selected_case_name = option_name
Rhino.RhinoApp.WriteLine(f"Case selected: {selected_case_name}")

# Handle the datasets based on user input
print(selected_case_name, selected_lines)
return selected_case_name, selected_lines

if __name__ == "__main__":

Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw() # 0 ms

command_line_input()



case_name = "your_case_name" # Replace with the actual case name
# polylines_guid_list = wood_rui_globals[case_name]["polylines_guid"]

# # Iterate through the list two items at a time
# for i in range(0, len(polylines_guid_list), 2):
# # Get the current GUIDs for both first and second items
# first_guid = polylines_guid_list[i] # Current index
# second_guid = polylines_guid_list[i + 1] # Next index (always exists)

# # Process the first object
# rhino_object_first = Rhino.RhinoDoc.ActiveDoc.Objects.Find(first_guid)
# for idx, v in enumerate(vectors[int(i * 0.5)]):
# name = f"insertion_vector_{idx}" # Use the same index for both
# value = f"{v.X} {v.Y} {v.Z}" # Ensure you are referencing the correct coordinates
# rhino_object_first.Attributes.SetUserString(name, value)

# # Process the second object
# rhino_object_second = Rhino.RhinoDoc.ActiveDoc.Objects.Find(second_guid)
# for idx, v in enumerate(vectors[int(i * 0.5)]):
# name = f"insertion_vector_{idx}" # Same name pattern
# value = f"{v.X} {v.Y} {v.Z}" # Ensure you are referencing the correct coordinates
# rhino_object_second.Attributes.SetUserString(name, value)
10 changes: 10 additions & 0 deletions src/rhino/plugin/commands/w_dataset_closest_points_joints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Rhino
import Rhino.Input
import Rhino.DocObjects
from typing import *
from wood_rui import wood_rui_globals


if __name__ == "__main__":

Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw() # 0 ms
57 changes: 27 additions & 30 deletions src/rhino/plugin/commands/w_dataset_folded_plates.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@
class dataset_folded_plates:
def __init__(
self,
dataset_name : str,
dataset_name: str,
surface: Rhino.Geometry.Surface,
u_divisions: int,
v_divisions: int,
base_planes: System.Collections.Generic.List[Rhino.Geometry.Plane],
thickness: float,
chamfer: float,
face_positions: System.Collections.Generic.List[float]
face_positions: System.Collections.Generic.List[float],
):

# Diamond Subdivision
self._dataset_name = dataset_name # type str
self._dataset_name = dataset_name # type str
self._mesh = Rhino.Geometry.Mesh() # type Mesh

self._flags = [] # List<bool>
Expand Down Expand Up @@ -585,28 +585,25 @@ def get_insertion_vectors(self):
for i in range(self._f):
for j in range(2):
self._f_polylines[i][j] = self.chamfer_polyline(self._f_polylines[i][j], -self._chamfer)


def create_dataset(self):


add_mesh(self._mesh, self._dataset_name)
flat_list_of_polylines = []
for i in range(0, len(self._f_polylines)):
for j in range(0, len(self._f_polylines[i])):
flat_list_of_polylines.append(self._f_polylines[i][j])
add_polylines(flat_list_of_polylines , self._dataset_name)
add_polylines(flat_list_of_polylines, self._dataset_name)
add_insertion_lines(self._insertion_lines, self._dataset_name)
add_adjacency(self._adjacency, self._dataset_name)
add_flags(self._flags, self._dataset_name)
Rhino.RhinoDoc.ActiveDoc.Views.Redraw() # 10-12ms
Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw() # 0 ms

# Rhino.RhinoDoc.ActiveDoc.Views.Redraw() # 10-12ms
Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw() # 0 ms


def get_base_planes() -> Tuple[Optional[List[rg.Plane]], rc.Result]:
base_planes: List[rg.Plane] = []

# Create a GetObject instance to select multiple curves
go: ric.GetObject = ric.GetObject()
go.SetCommandPrompt("Select multiple rectangle curves")
Expand Down Expand Up @@ -637,9 +634,10 @@ def get_base_planes() -> Tuple[Optional[List[rg.Plane]], rc.Result]:

if not base_planes:
return None, rc.Result.Failure

return base_planes, rc.Result.Success


def command_line_input(dataset_name) -> rc.Result:
# Create an instance of GetOption to define options in one line
get_options: ric.GetOption = ric.GetOption()
Expand All @@ -649,11 +647,11 @@ def command_line_input(dataset_name) -> rc.Result:
surface: Optional[rg.Surface] = None
u_divisions: ric.OptionInteger = ric.OptionInteger(5) # Default value 5
v_divisions: ric.OptionInteger = ric.OptionInteger(2) # Default value 2
thickness: ric.OptionDouble = ric.OptionDouble(4) # Default value 1.4
chamfer: ric.OptionDouble = ric.OptionDouble(3) # Default value 0.0
thickness: ric.OptionDouble = ric.OptionDouble(1.4) # Default value 1.4
chamfer: ric.OptionDouble = ric.OptionDouble(6) # Default value 0.0
face_positions: List[float] = [0.0] # Default list with a single value 0.0
base_planes: List[Rhino.Geometry.Plane] = []

# Add options to the GetOption instance with custom names
get_options.AddOption("select_surface") # New option to select surface
get_options.AddOptionInteger("u_divisions", u_divisions)
Expand All @@ -671,15 +669,15 @@ def command_line_input(dataset_name) -> rc.Result:
def update():
dataset_folded_plates(
dataset_name,
surface,
u_divisions.CurrentValue,
v_divisions.CurrentValue,
surface,
u_divisions.CurrentValue,
v_divisions.CurrentValue,
base_planes,
thickness.CurrentValue,
chamfer.CurrentValue,
face_positions # Pass face_positions to the UI
thickness.CurrentValue,
chamfer.CurrentValue,
face_positions, # Pass face_positions to the UI
)

update() # Run once to see the code input

while True:
Expand All @@ -690,7 +688,7 @@ def update():
return rc.Result.Cancel # Exit the loop

if res == Rhino.Input.GetResult.Option:

if get_options.OptionIndex() == 1: # 'select_surface'
# Step A: Select a surface
go: ric.GetObject = ric.GetObject()
Expand All @@ -699,13 +697,13 @@ def update():
go.EnablePreSelect(True, True)
go.DeselectAllBeforePostSelect = False
go.SubObjectSelect = False

if go.Get() != Rhino.Input.GetResult.Object:
return go.CommandResult()

surface_ref = go.Object(0)
surface: Optional[rg.Surface] = surface_ref.Surface()

if not surface:
print("No surface selected.")
return rc.Result.Failure
Expand All @@ -717,10 +715,10 @@ def update():
print("You have chosen to get base planes.")
# Call get_base_planes() immediately when option is selected
base_planes, result = get_base_planes()

if result != rc.Result.Success:
return result

print("Base planes selected:", len(base_planes) if base_planes else 0)
update()
continue
Expand All @@ -732,12 +730,12 @@ def update():
if gp.Get() != Rhino.Input.GetResult.String:
print("No input provided for face positions.")
return rc.Result.Failure

input_str = gp.StringResult()

try:
# Convert the input string to a list of floats
face_positions = [float(val.strip()) for val in input_str.split(',')]
face_positions = [float(val.strip()) for val in input_str.split(",")]
print("Face positions:", face_positions)
except ValueError:
print("Invalid input. Please enter valid numbers separated by commas.")
Expand All @@ -761,7 +759,6 @@ def update():
else:
update()


# Do something with the inputs (you can apply further operations here)
return rc.Result.Success

Expand Down
Loading

0 comments on commit 1502948

Please sign in to comment.