"""Reduce point count of polyline objects within tolerance
Mimics the behavior of the corresponding Grasshopper component
Uses RhinoCommon method Rhino.Geometry.Polyline.ReduceSegments
Preserves object color, layer and grouping
Script by Mitch Heynick 24 February, 2014"""

import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
from System import Guid

def pl_filt(rhino_object, geometry, component_index):
    return rs.IsPolyline(geometry)

def ReducePolylines():
    msg="Select polylines to process"
    crvIDs=rs.GetObjects(msg,4,preselect=True,custom_filter=pl_filt)
    if not crvIDs: return
    
    if sc.sticky.has_key("RPFittingTolerance"):
        def_tol = sc.sticky["RPFittingTolerance"]
    else:
        def_tol = 0.1
    absTol=sc.doc.ModelAbsoluteTolerance
    tol=rs.GetReal("Fitting Tolerance?",def_tol,absTol,)
    if tol == None: return
    
    rs.StatusBarProgressMeterShow("Processing curves",0,len(crvIDs),True,True)
    for i, crvID in enumerate(crvIDs):
        layer=rs.ObjectLayer(crvID)
        col_source=rs.ObjectColorSource(crvID)
        if col_source==1: color=rs.ObjectColor(crvID)
        groups=rs.ObjectGroups(crvID)
        obj=sc.doc.Objects.Find(crvID)
        rc,pl=Rhino.Geometry.PolylineCurve.TryGetPolyline(obj.Geometry)
        if rc:
            Rhino.Geometry.Polyline.ReduceSegments(pl,tol)
            if pl.IsValid:
                newCrvID=sc.doc.Objects.AddPolyline(pl)
                if newCrvID != Guid.Empty:
                    rs.ObjectLayer(newCrvID,layer)
                    if col_source==1: rs.ObjectColor(newCrvID,color)
                    if len(groups)>0:
                        for group in groups: rs.AddObjectsToGroup(newCrvID,group)
                    sc.doc.Objects.Delete(crvID, True)
        rs.StatusBarProgressMeterUpdate(i,True)
    sc.doc.Views.Redraw()
    rs.StatusBarProgressMeterHide()
    sc.sticky["RPFittingTolerance"] = tol
    
ReducePolylines()