Last active
July 8, 2020 04:18
-
-
Save pgolay/92c085b9964f3754fab3321d11c19a27 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Rhino | |
import scriptcontext as sc | |
import rhinoscriptsyntax as rs | |
import System | |
class DrawCrvCrvDeviationConduit(Rhino.Display.DisplayConduit): | |
def __init__(self, id1, id2, idx1, idx2): | |
self.textSize = 24 | |
self.id1 = id1 | |
self.id2 = id2 | |
self.edgeIdx1 = idx1 | |
self.edgeIdx2 = idx2 | |
self.hairScale = 0 | |
self.intSamples = 32 | |
self.interpCrv = None | |
self.blnDot = True | |
self.lineColor = System.Drawing.Color.Blue | |
self.minColor = System.Drawing.Color.Green | |
self.maxColor = System.Drawing.Color.Red | |
self.m_dirty = False | |
self.bbox = Rhino.Geometry.BoundingBox() | |
self.Start() | |
def Calculate(self): | |
tol = sc.doc.ModelAbsoluteTolerance | |
if self.edgeIdx1 == -1: | |
crv1 = rs.coercecurve (self.id1) | |
else: | |
brep = rs.coercebrep(self.id1) | |
edge = brep.Edges[self.edgeIdx1] | |
crv1 = edge.ToNurbsCurve() | |
if self.edgeIdx2 == -1: | |
crv2 = rs.coercecurve (self.id2) | |
else: | |
brep = rs.coercebrep(self.id2) | |
edge = brep.Edges[self.edgeIdx2] | |
crv2 = edge.ToNurbsCurve() | |
info = Rhino.Geometry.Curve.GetDistancesBetweenCurves(crv1, crv2, tol) | |
""" | |
rc 0 | |
out double maxDistance, 1 | |
out double maxDistanceParameterA, 2 | |
out double maxDistanceParameterB, 3 | |
out double minDistance, 4 | |
out double minDistanceParameterA, 5 | |
out double minDistanceParameterB 6 | |
If the max or min is on the end point of one of the curves, | |
find the closest point from that end back to the other curve and split off a subcrv to use instead. | |
""" | |
if info[0]: | |
dom1 = crv1.Domain | |
dom2 = crv2.Domain | |
crv2A = crv2.ClosestPoint(crv1.PointAt(dom1.Min))[1] | |
crv2B = crv2.ClosestPoint(crv1.PointAt(dom1.Max))[1] | |
domList = sorted([crv2A,crv2B]) | |
dom2Ex = Rhino.Geometry.Interval(domList[0], domList[1]) | |
exCrv = crv2.Trim(dom2Ex) | |
if exCrv is not None: | |
crv2 = exCrv | |
crv1A = crv1.ClosestPoint(crv2.PointAt(dom2.Min))[1] | |
crv1B = crv1.ClosestPoint(crv2.PointAt(dom2.Max))[1] | |
domList = sorted([crv1A,crv1B]) | |
dom1Ex = Rhino.Geometry.Interval(domList[0], domList[1]) | |
exCrv = crv1.Trim(dom1Ex) | |
if exCrv is not None: | |
crv1 = exCrv | |
pars = crv1.DivideByCount(self.intSamples,True) | |
self.pts = [crv1.PointAt(par) for par in pars] | |
self.crvPts = [crv2.PointAt(crv2.ClosestPoint(pt)[1]) for pt in self.pts] | |
self.Distances = [] | |
self.Lines = [] | |
info = Rhino.Geometry.Curve.GetDistancesBetweenCurves(crv1, crv2, tol) | |
if info[0]: | |
self.maxDist = info[1] | |
self.maxLoc = crv2.PointAt(info[3]) | |
maxEndPt = crv1.PointAt(info[2]) | |
self.minDist = info[4] | |
self.minLoc = crv2.PointAt(info[6]) | |
minEndPt = crv1.PointAt(info[5]) | |
for i in range(len(self.pts)): | |
self.Lines.append(Rhino.Geometry.Line(self.pts[i],self.crvPts[i]) ) | |
for pt in self.pts: | |
self.bbox.Union(pt) | |
for pt in self.crvPts: | |
self.bbox.Union(pt) | |
self.maxLine = Rhino.Geometry.Line(self.maxLoc, maxEndPt) | |
self.minLine = Rhino.Geometry.Line(self.minLoc, minEndPt) | |
return self.maxDist,self.minDist, self.minLine, self.maxLine, self.bbox, self.Lines | |
def Start(self): | |
# Create event handlers | |
self.CreateEvents() | |
if sc.sticky.has_key('CRVDEVIATION_SAMPLES'): | |
self.intSamples = sc.sticky['CRVDEVIATION_SAMPLES'] | |
if sc.sticky.has_key('CRVDEVIATION_HAIRSCALE'): | |
intScale = sc.sticky['CRVDEVIATION_HAIRSCALE'] | |
self.hairScale = pow(2, intScale)/100 | |
if sc.sticky.has_key('CRVDEVIATION_TEXT_USAGE'): | |
self.blnDot = sc.sticky['CRVDEVIATION_TEXT_USAGE'] | |
# Enable conduit | |
self.Enabled = True | |
# Stop the conduit | |
def Stop(self): | |
# Remove event handlers | |
self.RemoveEvents() | |
# Disable conduit | |
self.Enabled = False | |
def CreateEvents(self): | |
Rhino.RhinoDoc.CloseDocument += self.OnCloseDocument | |
Rhino.RhinoDoc.ReplaceRhinoObject += self.OnReplaceObject | |
Rhino.RhinoDoc.DeleteRhinoObject += self.OnDeleteObject | |
Rhino.RhinoApp.Idle += self.OnIdle | |
# Remove Rhino event handlers | |
def RemoveEvents(self): | |
Rhino.RhinoDoc.CloseDocument -= self.OnCloseDocument | |
Rhino.RhinoDoc.ReplaceRhinoObject -= self.OnReplaceObject | |
Rhino.RhinoDoc.DeleteRhinoObject -= self.OnDeleteObject | |
Rhino.RhinoApp.Idle -= self.OnIdle | |
# RhinoDoc.ReplaceRhinoObject event handler | |
def OnReplaceObject(self, sender, e): | |
if e.ObjectId == self.id1 or e.ObjectId == self.id2 : | |
self.hairScale = 0 | |
self.intSamples = 32 | |
self.blnDot = True | |
if sc.sticky.has_key('CRVDEVIATION_SAMPLES'): | |
self.intSamples = sc.sticky['CRVDEVIATION_SAMPLES'] | |
if sc.sticky.has_key('CRVDEVIATION_HAIRSCALE'): | |
intScale = sc.sticky['CRVDEVIATION_HAIRSCALE'] | |
self.hairScale = pow(2, intScale)/100 | |
if sc.sticky.has_key('CRVDEVIATION_TEXT_USAGE'): | |
self.blnDot = sc.sticky['CRVDEVIATION_TEXT_USAGE'] | |
self.m_dirty = True | |
def OnDeleteObject(self, sender, e): | |
if e.ObjectId == self.id1 or e.ObjectId == self.id2 : | |
if not self.m_dirty: | |
self.Stop() | |
self.id1 = None | |
self.id2 = None | |
if sc.sticky.has_key("CurveCurveDeviationConduit"): | |
sc.sticky.Remove("CurveCurveDeviationConduit") | |
def OnIdle(self, sender, e): | |
if self.m_dirty == True: | |
self.calculate() | |
self.m_dirty = False | |
def OnCloseDocument(self, sender, e): | |
self.Stop() | |
self.id1 = None | |
self.id2 = None | |
def CalculateBoundingBox(self, e): | |
e.IncludeBoundingBox(self.bbox) | |
def DrawForeground(self, e): | |
self.Calculate() | |
for line in self.Lines: | |
e.Display.DrawLine(line, self.lineColor) | |
e.Display.DrawLine(self.maxLine, System.Drawing.Color.Aqua) | |
e.Display.DrawLine(self.minLine, System.Drawing.Color.Aqua) | |
def DrawOverlay(self, e): | |
self.Calculate() | |
# | |
# for line in self.Lines: | |
# e.Display.DrawLine(line, self.lineColor) | |
# | |
# e.Display.DrawLine(self.maxLine, System.Drawing.Color.Chartreuse) | |
# e.Display.DrawLine(self.minLine, System.Drawing.Color.Chartreuse) | |
# | |
if not self.blnDot: | |
e.Display.Draw2dText("Max " + str(round((self.maxDist),4)), System.Drawing.Color.White, self.maxLoc, True, self.textSize) | |
e.Display.Draw2dText("Min " + str(round((self.minDist),4)), System.Drawing.Color.White, self.minLoc, True, self.textSize) | |
else: | |
e.Display.DrawDot(self.maxLoc, "Max " + str(round((self.maxDist),4)), System.Drawing.Color.White, System.Drawing.Color.Black) | |
e.Display.DrawDot(self.minLoc, "Min " + str(round((self.minDist),4)), System.Drawing.Color.White, System.Drawing.Color.Black) | |
def DrawCrvCrvDeviation(): | |
if sc.sticky.has_key("CurveCurveDeviationConduit"): | |
conduit = sc.sticky["CurveCurveDeviationConduit"] | |
conduit.Stop() | |
conduit = None | |
sc.sticky.Remove("CurveCurveDeviationConduit") | |
sc.doc.Views.Redraw() | |
print "Curve-Curve deviation display has been turned off." | |
return | |
while True: | |
blnDot = True | |
if sc.sticky.has_key('CRVDEVIATION_TEXT_USAGE'): | |
blnDot = sc.sticky['CRVDEVIATION_TEXT_USAGE'] | |
go = Rhino.Input.Custom.GetObject() | |
go.GeometryFilter = Rhino.DocObjects.ObjectType.Curve|Rhino.DocObjects.ObjectType.EdgeFilter | |
go.SetCommandPrompt("Select two curves to test.") | |
opDot = Rhino.Input.Custom.OptionToggle(blnDot,"Text", "Dot") | |
go.AddOptionToggle("TextMode", opDot) | |
go.SubObjectSelect=True | |
crvRC = go.GetMultiple(2,2) | |
if ( go.CommandResult() != Rhino.Commands.Result.Success ): | |
return | |
if crvRC == Rhino.Input.GetResult.Option: | |
blnDot = opDot.CurrentValue | |
sc.sticky['CRVDEVIATION_TEXT_USAGE'] = blnDot | |
continue | |
if crvRC == Rhino.Input.GetResult.Object: | |
objs = [go.Object(i) for i in range(go.ObjectCount)] | |
ids = [] | |
idxs = [] | |
for obj in objs: | |
idxs.append(obj.GeometryComponentIndex.Index) | |
ids.append(obj.ObjectId) | |
break | |
# id1 = rs.GetObject("Select the first curve",filter=4, preselect=True) | |
# if not id1: return | |
# crv1 = rs.coercecurve (id1) | |
# | |
# id2 = rs.GetObject("Select the second curve",filter=4) | |
# if not id2: return | |
# crv2 = rs.coercecurve(id2) | |
conduit = None | |
conduit = DrawCrvCrvDeviationConduit( ids[0], ids[1], idxs[0], idxs[1]) | |
sc.sticky["CurveCurveDeviationConduit"] = conduit | |
sc.sticky['CRVCRVDEVIATION_INPUT'] = ids | |
conduit.Enabled = True | |
sc.doc.Views.Redraw() | |
print "Curve-Curve deviation display is now on." | |
if __name__ == '__main__':DrawCrvCrvDeviation() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment