PythonScript for fillet polycurve with click in the corner


#1

Hi All
Below script for fillet corner curve with one click:

#-*- encoding: UTF-8 -*-
import rhinoscriptsyntax as rs

def cc(C,C1,raggio,curve):  #controllo per vedere se è possibile il raccordo
                            # come nel caso che è già stato raccordato
    if rs.IsArc(C) or rs.IsArc(C1): #se una delle due curve è un arco
        rs.EnableRedraw(False)
        rs.SelectObject(C)
        rs.SelectObject(C1)
        rs.Command("_Intersect")
        result=rs.LastCommandResult()
        if result==0:
            
            pint=rs.FirstObject()
            if rs.IsPoint(pint):
               param1=rs.CurveClosestPoint(C,pint)
               param2=rs.CurveClosestPoint(C1,pint)
               t1=rs.CurveTangent(C,param1)  # se le due curve sono tangenti non eseguo il raccordo
               t2=rs.CurveTangent(C1,param2)
               if round(t1[0],3)==round(t2[0],3):                   
                   rs.DeleteObjects(curve)
                   rs.DeleteObject(pint)
                   rs.EnableRedraw(True)
                   rs.MessageBox("Corner already fillected click near\nthecorner  or Enter for Exit")
                   return "vero"  # cioè le due curve sono tangenti
               rs.DeleteObject(pint)
        rs.EnableRedraw(True)
        return        
               
def filletp(arrdati,raggio):  
    idcurve=arrdati[0]
    pickPoint=arrdati[3]    
    curve=rs.ExplodeCurves(idcurve)# duplico gli elementi della polycurva
    #print len(curve)
    listacurve=[]
    for curva in curve: # cerco la curva selezionata ed estraggo pstart e pend       
        param=rs.CurveClosestPoint(curva,pickPoint)
        ptest=rs.EvaluateCurve(curva,param)
        if rs.PointCompare(pickPoint,ptest,0.01):
            C=curva            
            pstart=rs.CurveStartPoint(curva)
            pend=rs.CurveEndPoint(curva)
            distS=rs.Distance(ptest,pstart)
            distE=rs.Distance(ptest,pend)
            if distS<distE:
                pfillet=pstart
                stp="pend"                  
            else:
                pfillet=pend
                stp="pstart"                
        else:
            listacurve.append(curva)          
    C1=""
    for crv in listacurve: # vado in cerca della curva con la quale fare il fillet       
        if stp=="pend":             
            pestremo=rs.CurveEndPoint(crv)
            if rs.PointCompare(pfillet,pestremo,0.01):                
                C1=crv                
                break
        else:    # se il punto è il pstart        
            pestremo=rs.CurveStartPoint(crv)
            if rs.PointCompare(pfillet,pestremo,0.01):
                C1=crv                
                break
    if C1=="" :
        rs.DeleteObjects(curve) #se non c'è C1 termino
        return    
    vero=cc(C,C1,raggio,curve) # chiamo la def di controllo curve tangenti    
    if vero=="vero":return  # se curve tangenti esco dal ciclo
    dati=rs.CurveFilletPoints(C,C1,raggio,pfillet,pestremo)  # punti per trimmare le curve
    if dati==None:
        rs.MessageBox("radius too large")   
        rs.DeleteObjects(curve)
        return raggio,"raggiogrande"
    fillet=rs.AddFilletCurve( C, C1,raggio,pfillet,pestremo )     # eseguo il fillet 
    
    #return
    if fillet==None: rs.MessageBox("fillet impossible")
    
    prC=dati[0]
    prC1=dati[1]     
    domainC=rs.CurveDomain(C)  # parametri per trimmare
    paramC=rs.CurveClosestPoint(C,prC)
    domainC1=rs.CurveDomain(C1)
    paramC1=rs.CurveClosestPoint(C1,prC1)     
    if stp=="pstart":        # trimmatura curve
        #rs.SelectObject(C)
        C=rs.TrimCurve ( C, (domainC[0],paramC), delete_input=True )
        C1=rs.TrimCurve(C1,(paramC1,domainC1[1]), delete_input=True)
        print C1
    else:
        C1=rs.TrimCurve ( C1, (domainC[1],paramC1), delete_input=True )
        C=rs.TrimCurve(C,(paramC,domainC[0]), delete_input=True)        
    lc=(listacurve+[C,C1,fillet])# la lista delle curve
    cf=[]
    for c in lc:# siccome nella lista c'è l'id di un elemento cancellato devo eliminarlo
        if rs.IsObject(c): 
            cf.append(c)            
    rs.JoinCurves(cf,True)
    rs.DeleteObject(idcurve)
def fillet():
    k=0
    raggio=rs.GetDocumentData("RMAraggioPolycurve","raggio")
    st="Fillet radius <Enter to confirm>"
    while True:
        if raggio=="" or raggio==None: raggio="5"
        nraggio=rs.GetReal(st,float(raggio))
        if nraggio==raggio and k!=0:break
        raggio=nraggio
        rs.SetDocumentData("RMAraggioPolycurve","raggio",str(nraggio))
        while True:             
            k+=1
            #raggio=rs.GetReal("raggio fillet <Enter per confermare>",float(raggio)) 
            arrdati=rs.GetCurveObject("select near vertex of polycurves to fillet or <Enter per nuovo valore raggio fillet>") 
            rs.EnableRedraw(False)
            if arrdati==None:
                break
            dati=filletp(arrdati,raggio)
            rs.EnableRedraw(True)
            if dati!=None:
                raggio=dati[0]
                stringa="raggiogrande"
                if stringa=="raggiogrande":
                    raggio=rs.GetReal("Enter  smaller radius ",raggio)
        st="New fillet value  or <Enter for exit >"
        rs.SetDocumentData("RMAraggioPolycurve","raggio",str(raggio))
    
if __name__=='__main__':
    fillet()

Ciao Vittorio


(Steve Baer) #2

Thanks for sharing. One recommendation I would make would be to provide clear descriptive names for your functions. A function named “cc” is difficult to quickly understand what it does solely based on the name.


#3

Hi Steve
You’re Right.

cc is the function that checks if is possible to do the fillet:

Ciao Vittorio