A triangulated pattern instead, could be a good solution in the case of a complex set of boundaries and features (holes, etc.), since, in this case, the definition of only two clear directions for the flow of forces is not possible.
Outer boundary is a closed polycurve that represents the outline of the diagram.
# ==============================================================================# Create Pattern# ==============================================================================boundary_guids = compas_rhino.select_curves('Select outer boundary.')compas_rhino.rs.UnselectAllObjects()target_length =1.0gkey_constraints ={}# outer boundaryboundary = []for guid in boundary_guids: compas_rhino.rs.EnableRedraw(False) segments = compas_rhino.rs.ExplodeCurves(guid)for segment in segments: curve = RhinoCurve.from_guid(segment) N =max(int(curve.length() / target_length), 1) points =map(list, curve.divide(N, over_space=True))for point in points: gkey =geometric_key(point)if gkey notin gkey_constraints: gkey_constraints[gkey]= [] gkey_constraints[gkey].append(segment) boundary.extend(points) compas_rhino.rs.HideObjects(segments) compas_rhino.rs.EnableRedraw(True)area = target_length **2*0.5*0.5*1.732proxy =Proxy()proxy.package ='compas.geometry'vertices, faces = proxy.conforming_delaunay_triangulation(boundary, angle=30, area=area)vertices[:]= [[float(x),float(y),float(z)] for x, y, z in vertices]pattern = Pattern.from_vertices_and_faces(vertices, faces)
Inner boundaries are openings of the intended design pattern.
hole_guids = compas_rhino.select_curves('Select inner boundaries.')compas_rhino.rs.UnselectAllObjects()# hole polygonspolygons = []if hole_guids:for guid in hole_guids: curve = RhinoCurve.from_guid(guid) N =int(curve.length() / target_length)or1 points =map(list, curve.divide(N, over_space=True))for point in points[:-1]: gkey =geometric_key(point)if gkey notin gkey_constraints: gkey_constraints[gkey]= [] gkey_constraints[gkey].append(guid) polygons.append(points)
Another more manual way to make holes is to delete the vertices and modify the vertices inside the hole and modify the vertices on the boundary of the hole to achieve the target shape.
TODO: add select and delete?
Constraint curves are where the vertices and edges will be forced to snapped onto.
segments_guids = compas_rhino.select_curves('Select constraint curves.')compas_rhino.rs.UnselectAllObjects()# constraint polylinespolylines = []if segments_guids:for guid in segments_guids: curve = RhinoCurve.from_guid(guid) N =int(curve.length() / target_length)or1 points =map(list, curve.divide(N, over_space=True))for point in points: gkey =geometric_key(point)if gkey notin gkey_constraints: gkey_constraints[gkey]= [] gkey_constraints[gkey].append(guid) polylines.append(points)
Ex. Create Free-form Vault from Triangulation
Step 1: Generate Pattern from Triangulation
After the pattern is generated, the session could be serialized.
HERE = os.path.dirname(__file__)FILE_O = os.path.join(HERE, 'data', 'triangulation.json')pattern.to_json(FILE_O)
It's relatively hard to select a specific edge to compute sag, here all edges are saged at the same time.
Step 3: Generate FormDiagram
form = FormDiagram.from_pattern(pattern)
Step 4: Generate ForceDiagram
force = ForceDiagram.from_formdiagram(form)
Strep 5: Horizontal Equilibrium
Step 6: Vertical Equilibrium
Serialization, Rhino script and RV2 Session
So each diagram could be saved to json and visualize them for later use. Unfortunately, currently RV2 cannot read the FormDiagram, ForceDiagram or ThrustDiagram directly from json. The in RV2, the user could use save session and load session could let you save the ongoing session and reuse it. If a specific diagram needs to be loaded, the following code could be used.