Multiple chamfers

Hello, do you know how can I achieve something like this:

I mean: chamfer over chamfer to create faceted round-like edges. But automatically. A macro maybe?

Hi @Bruno_E1 - You can run the ChamferEdge command as many times as you want and chamfer the previously chamfered edge. You can use the Repeat command, followed by ChamferEdge. This will run the ChamferEdge command in a loop so you don’t need to execute it over and over again.

thanks I will try with Repeat

“Repeat”, followed by “ChamferEdge”, will not create equally spaced chamfers when executing them multiple time. IS there a way to have equal sides of the multi-chamfers? 3DS Max have this functionality for poly models.

I agree. I was also hoping to find a more automated solution. Ideally, something that doesn’t require to select more than the initial edges and define a number of sides to create. I find myself in the need to use it very often.

Currently, you can workaround that limitation by following these steps:

  1. Extract the fillet surface.
  2. Run “Rebuild surface” (change Degree 2 into Degree 1 from its pop-up window and play with the Point count numbers) or “Rebuild surface UV” (with the Type=StraightSections selected).
  3. Use “Divide surface along creases” to divide the converted surface into the number of flat surfaces that you wanted. Now you have a chamfer with equally spaced walls.

You can automate these 3 steps with the following macro:
! _ExtractSrf _Pause _Rebuild _Pause _DivideAlongCreases

The tooltip that I added to this is “Multi chamfer after Fillet edge” :slight_smile:

Hello,

since it has been Christmas recently, here is a pythonscript doing this. :slight_smile: Hope it works. Be aware to set to select the edge right in the middle. No warranty, take it as a starting point. What’s the reason to do so many chamfers, and why not using a radius instead?

import rhinoscriptsyntax as rs
import Rhino
import Rhino.Geometry as rg
import scriptcontext

from threading import Thread
from time import sleep

REPEAT = 3
WAIT = 1 #secs

#Selection
edgeSelection = rs.GetEdgeCurves("Select Brep edges",1,1)[0]

CURVE_ID = edgeSelection[0]
PARENT_ID = edgeSelection[1]
SELECTIONPOINT = edgeSelection[2]
BREP = None

def findTwoClosestEdges(searchpoint):
    global BREP,PARENT_ID 
    
    ##rs.AddPoint(searchpoint)
    #searching adjacent edges
    minDis = float.MaxValue
    secondMinDis = float.MaxValue
    index = [-1,-1]
    ##mes = "\n\n"
    for edgeNode in BREP.Edges: 
        edge = edgeNode.EdgeCurve
        
        t = edge.ClosestPoint(searchpoint)[1]
        cp = edge.PointAt(t)
        dis = cp.DistanceTo(searchpoint)
        ##scriptcontext.doc.Objects.AddPoint(cp)
        ##mes +="  %f \n" %(dis)
       
        if dis < minDis:
            secondMinDis = minDis
            minDis = dis
            index[1] = index[0] 
            index[0] = edgeNode
        elif dis < secondMinDis:
            secondMinDis = dis
            index[1] = edgeNode
    ##mes += "\n\n"
    ##print mes
    ##print "%f %f" % (minDis,secondMinDis)
    # Unselect
    rs.UnselectAllObjects()
    # reselect relative
    robj = Rhino.RhinoDoc.ActiveDoc.Objects.Find(PARENT_ID)
    robj.SelectSubObject(index[0].ComponentIndex(),True,True)
    robj.SelectSubObject(index[1].ComponentIndex(),True,True)
    #redraw
    scriptcontext.doc.Views.Redraw()  
    # return selected edges
    ptA = index[0].EdgeCurve.PointAt(index[0].EdgeCurve.Domain.Mid)
    ptB = index[1].EdgeCurve.PointAt(index[1].EdgeCurve.Domain.Mid)
    return (ptA,ptB)


SEARCHPOINTS = None
def asyncSelection(edge):
    global SEARCHPOINTS
    sleep(WAIT)
    SEARCHPOINTS = findTwoClosestEdges(edge)
    sleep(0.3)
    
def recursiveChamfer(level,searchpoint):
    global SEARCHPOINTS, BREP,PARENT_ID, CURVE_ID
    BREP = rs.coercebrep(PARENT_ID)
    level+=1  
    if level >= REPEAT:
        return
    elif level == 0: # initial chamfer
        rs.SelectObject(CURVE_ID)
        Rhino.RhinoApp.RunScript("_ChamferEdge _Enter _Enter",True) 
        recursiveChamfer(level,searchpoint)
        
    else: 

        thread = Thread(target = asyncSelection, args = (searchpoint,))
        thread.start()
        thread.join()
        Rhino.RhinoApp.RunScript("_ChamferEdge _Enter _Enter",True)

        
        if SEARCHPOINTS != None:
            searchpointA = SEARCHPOINTS[0]
            searchpointB = SEARCHPOINTS[1]   
            recursiveChamfer(level,searchpointA)
            recursiveChamfer(level,searchpointB)


recursiveChamfer(-1,SELECTIONPOINT)

This is what happened at level 3 recursion with one selected edge:
Level3Chamfer

3 Likes

thank you very much for the script work. I’m trying it. Unfortunately, I’m having trouble. I always get: " no attribute ‘EdgeCurve’ ". I guess I may be doing something wrong…

What’s the reason to do so many chamfers, and why not using a radius instead?

In this context, I avoid using any curved surfaces because everything will be converted to meshes and imported in UE4.
I use chamfer and then “weld mesh edges” on corner’s edges. So that my mesh results in fewer polygons, more quads, fewer triangles and it’s easier to unwrap.

mhh, I’ll test it on R5 as soon as I find time for it. Its made in R6.