This issue is kind of continuation of an issue solved before, but now involving subd - regards this, there is another issue now.
I would like to know a way to transform a mesh into a subd and crease some points (vertices) in grasshopper. I managed to crease some points in rhinoceros manually, but I would like to make this automatic in grasshopper.
As the image shows, there is creases forming loops, making a round crease shape, but actually I would like to have straight crease. This is achieved when creasing the vertices manually after baked the subd geometry, as the image shows:
But, I would like to control the output in grasshopper, putting as many creased points as necessary (principally to achieve the result obtained manually), also determining their locations.
Is there a way to do this in grasshopperâs components? A plugin could be useful? Or maybe a script could be made to solve that?
I saw some script along the forum, but they does not work for my case.
I tried a python script made with the help of ChatGPT (sorry, but I am a newbie in python and other languages, I barely know how to print âHello, World!â), but it does not work (I kind of looped through ChatGPTâs responses to get the desired result to fix the errors, but the result is still a rounded crease).
import Rhino
import rhinoscriptsyntax as rs
# Inputs:
# subd_geometry: SubD geometry (input from the SubD component)
# points: List of points (Type: Point3d, list of points to apply crease)
# Initialize list to store the indices of the vertices to be adjusted
crease_vertices = []
# Debug: Check the types of the inputs
if subd_geometry is None:
print("subd_geometry is empty or not connected properly.")
else:
print(f"subd_geometry is connected. Type: {type(subd_geometry)}")
if points is None:
print("points is empty or not connected properly.")
else:
print(f"points is connected. Type: {type(points)}")
# Ensure 'points' is a list
if not isinstance(points, list):
points = [points]
# Iterate over the specified points and find the closest vertex
for pt in points:
if not isinstance(pt, Rhino.Geometry.Point3d):
print(f"Invalid point detected: {pt} (Type: {type(pt)})")
continue # Skip to the next point if the current one is not Point3d
closest_index = -1
closest_distance = float("inf")
# Iterate over the vertices of the SubD
for i in range(subd_geometry.Vertices.Count):
vertex = subd_geometry.Vertices[i].Location
dist = pt.DistanceTo(vertex)
# Check for the closest vertex
if dist < closest_distance:
closest_distance = dist
closest_index = i
# Define a maximum tolerance to consider a vertex as close
tolerance = 1 # Adjust as necessary
if closest_distance <= tolerance:
if closest_index not in crease_vertices:
crease_vertices.append(closest_index)
print(f"Vertex {closest_index} is close to {pt} (Distance: {closest_distance})")
else:
print(f"No close vertex found for {pt} (Minimum Distance: {closest_distance})")
# Apply the crease to the found vertices
if crease_vertices:
for idx in crease_vertices:
# Apply crease with weight 1.0 (can adjust as necessary)
subd_geometry.SetVertexCrease(idx, 1.0)
print(f"Applied crease to vertices: {crease_vertices}")
else:
print("No vertex received the crease.")
# Output the updated SubD
a = subd_geometry
It told me to increase the tolerance in the search for a vertex relative to the given set of points, but that does not work either. I checked the distance between the vertices of the subd and the given points, and apparently all of them can be reached within a tolerance radius of â1â, as the script shows.
Also, it returns 20 equal results (the same amount of points in the point component, even flattened).
Maybe there is a way to solve this based on what Chat created?
I was messing with some components to see which vertices have creases, and apparently the vertices I want to crease are already creases, so I do not understand what is happening, I am probably misunderstanding.
Thank you very much, Martin, but I have already tested the script before this topic. On the other hand, I was thinking that I needed the endpoints of the edges to crease at that moment, not the midpoints, but that still does not work. They are creased, but forming a round shape, before and after passing through the script. Maybe, I am still doing something wrong.
Yes. I tried another way: I baked the subd, then creased the points, resulting in the second image of this topic again. After that, I selected the subd in grasshopper and saw that there are no more creases in the vertices that I had creased manually, but actually âcornersâ. In a basic search, I discovered that subds have 4 types of vertices: smooth, crease, dart and corner. Filtering the information, I saw that now the vertices with crease applied have become these corners. So, I need a code to transform these vertices into âcornersâ. On the other hand, I can imagine that it is possible to create the subd from a mesh already with these âcornersâ, but I donât know how to do that.
I saw that, when setting âtrueâ to sharp in the TriRemesh component, the subd creates âcornersâ, but thatâs not exactly what I would like to have in the final shape (it needs to have âcornersâ only in the steps, as the obtained mesh had, to have smooth plateaus). This is related to the creation of the mesh. Maybe another way of creating the mesh can also solve this problem.
Playing around with the subd components, I saw something called âSubD Vertex Tagsâ, to modify a subd with indexes and tags (smooth, crease, corner, dart): I proceeded with that to apply âcornerâ to specific vertices. Nothing happens, it just creates an invalid subd and, filtering the corners, something strange occurs, messing up the location of the corners that I would like to become âcornersâ (even applying individually each vertex to become a âcornerâ, it does not work).
Thanks for your examples, Martin. The intention was to have like a perfect plateau for buildings, like boxes on a surface. This surface is a topography, so that when making a section, the boundary of the building will fit exactly with the boundaries of the plateaus (if the plateaus are so smooth, like a round shape, it will not align). On the other hand, everything else needs to be smooth, like a topography is - the plateaus are human-made cuts, with sharp edges, not natural like natural topography is). So in my thinking, with a subd, I would achieve this smoothness and sharpness edges at the same time.
Sorry for the late reply Martin, I just left the topic aside to focus on other issues. I tried your approach but did not get the result from your screenshot. Can you show me your workflow?