Skip to content

Instantly share code, notes, and snippets.

@pgolay
Last active July 1, 2019 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pgolay/b2d11ef3eacdd743f56dd8fc3a87a47e to your computer and use it in GitHub Desktop.
Save pgolay/b2d11ef3eacdd743f56dd8fc3a87a47e to your computer and use it in GitHub Desktop.
import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc
import System.Drawing as drawing
def SubCrvFromMid():
crvColor = Rhino.ApplicationSettings.AppearanceSettings.TrackingColor
oRef = rs.GetObject("Select a curve to shorten.",4, preselect=True, subobjects=True)
if not oRef: return
geo = oRef.Geometry()
id = oRef.ObjectId
crv = geo.ToNurbsCurve()
while True:
copy=False
if sc.sticky.has_key('COPY_SUBCRV'):
copy = sc.sticky['COPY_SUBCRV']
gPoC = Rhino.Input.Custom.GetPoint()
gPoC.SetCommandPrompt("Set sub-curve midpoint.")
gPoC.Constrain(crv, True)
if not isinstance(geo, Rhino.Geometry.BrepEdge):
opCopy = Rhino.Input.Custom.OptionToggle(copy,"No", "Yes")
gPoC.AddOptionToggle("Copy", opCopy)
rc = gPoC.Get()
if gPoC.CommandResult()!=Rhino.Commands.Result.Success:
return gPoC.CommandResult()
if rc==Rhino.Input.GetResult.Option:
copy = opCopy.CurrentValue
sc.sticky['COPY_SUBCRV'] = copy
continue
if rc==Rhino.Input.GetResult.Point:
pt = gPoC.Point()
break
if not pt: return
baseParRC, basePar = crv.ClosestPoint(pt)
if crv.IsClosed:
crv.ChangeClosedCurveSeam(basePar)
crv.ChangeClosedCurveSeam(crv.Domain.Mid)
baseParRC, basePar = crv.ClosestPoint(pt)
# def GetPointDynamicDrawFunc( sender, args ):
# try:
# args.Display.DrawPoint(pt)
# parRC, par = crv.ClosestPoint(args.CurrentPoint)
# if parRC:
# diff = par-basePar
# par2 = basePar-diff
# p2 = crv.PointAt(par2)
#
# args.Display.DrawPoint(p2)
# args.Display.DrawPoint(args.CurrentPoint)
#
# parList = sorted([par,par2])
# tCrv = crv.Trim(parList[0], parList[1])
# if tCrv:
# if tCrv.IsValid:
# args.Display.DrawCurve(tCrv, crvColor)
# except Exception as ex:
# print ex
def GetPointDynamicDrawFunc( sender, args ):
args.Display.DrawPoint(pt)
parRC, par = crv.ClosestPoint(args.CurrentPoint)
if parRC:
diff = par-basePar
par2 = basePar-diff
if par2> crv.Domain.Max:
par2 = crv.Domain.Max
elif par2 < crv.Domain.Min:
par2 = crv.Domain.Min
p2 = crv.PointAt(par2)
args.Display.DrawPoint(p2)
args.Display.DrawPoint(args.CurrentPoint)
parList = sorted([par,par2])
tCrv = crv.Trim(parList[0], parList[1])
if tCrv:
if tCrv.IsValid:
args.Display.DrawCurve(tCrv, crvColor)
while True:
copy=False
if sc.sticky.has_key('COPY_SUBCRV'):
copy = sc.sticky['COPY_SUBCRV']
gp = Rhino.Input.Custom.GetPoint()
gp.SetCommandPrompt("Set sub-curve end")
gp.AcceptNumber(True, True)
gp.DynamicDraw += GetPointDynamicDrawFunc
if not isinstance(geo, Rhino.Geometry.BrepEdge):
opCopy = Rhino.Input.Custom.OptionToggle(copy,"No", "Yes")
gp.AddOptionToggle("Copy", opCopy)
gp.Constrain(crv, True)
rc = gp.Get()
if gp.CommandResult()!=Rhino.Commands.Result.Success:
return gp.CommandResult()
if rc==Rhino.Input.GetResult.Number:
length = gp.Number()
sCrvs = crv.Split(basePar)
sCrvs[0].Reverse()
ptLen1 = sCrvs[0].PointAtLength(length)
if ptLen1:
tempRc, parStart = crv.ClosestPoint(ptLen1)
else:
parStart = crv.Domain.Min
tempRC = None
ptLen2 = sCrvs[1].PointAtLength(length)
if ptLen2:
tempRc, parEnd = crv.ClosestPoint(ptLen2)
else:
parEnd = crv.Domain.Max
break
if rc==Rhino.Input.GetResult.Option:
copy = opCopy.CurrentValue
sc.sticky['COPY_SUBCRV'] = copy
continue
if rc==Rhino.Input.GetResult.Point:
p1 = gp.Point()
sCrvs = crv.Split(basePar)
sCrvs[0].Reverse()
parRC, parStart = crv.ClosestPoint(p1)
tempList = sorted([basePar,parStart])
length = crv.GetLength(Rhino.Geometry.Interval(tempList[0], tempList[1]))
if parStart < basePar:
if sCrvs[1].GetLength() < length:
ptEnd = sCrvs[1].PointAtEnd
else:
ptEnd = sCrvs[1].PointAtLength(length)
else:
if sCrvs[0].GetLength() < length:
ptEnd = sCrvs[0].PointAtEnd
else:
ptEnd = sCrvs[0].PointAtLength(length)
parRC, parEnd = crv.ClosestPoint(ptEnd)
break
parList = sorted([parStart,parEnd])
tCrv = crv.Trim(parList[0], parList[1])
if isinstance(geo, Rhino.Geometry.BrepEdge): copy=True
if copy:
tCrvId = sc.doc.Objects.AddCurve(tCrv)
rs.MatchObjectAttributes(tCrvId, id)
sc.doc.Objects.UnselectAll()
sc.doc.Objects.Select(tCrvId)
else:
sc.doc.Objects.Replace(id, tCrv)
sc.doc.Views.Redraw()
if __name__ == '__main__':SubCrvFromMid()
@pgolay
Copy link
Author

pgolay commented Jun 28, 2019

Added added support for length constraint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment