Last active
July 9, 2018 15:48
-
-
Save pgolay/0bdacb2ffb45cda7f2054688f26745e4 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 rhinoscriptsyntax as rs | |
import scriptcontext as sc | |
import System.Guid | |
import math | |
def GetMarkerOptions(crvLength): | |
while True: | |
num = 0 | |
if sc.sticky.has_key("SEW_START_NUMBER"): | |
num = sc.sticky["SEW_START_NUMBER"] | |
prefix = None | |
if sc.sticky.has_key("SEW_NUMBER_PREFIX"): | |
prefix = sc.sticky["SEW_NUMBER_PREFIX"] | |
addNum = True | |
if sc.sticky.has_key("ADD_SEW_NUMBERS"): | |
addNum = sc.sticky["ADD_SEW_NUMBERS"] | |
dblSize = 1 | |
if sc.sticky.has_key("SEAM_MARKER_SIZE"): | |
dblSize = sc.sticky["SEAM_MARKER_SIZE"] | |
divLen = 1 | |
if sc.sticky.has_key("SEW_DIV_LENGTH"): | |
divLen = sc.sticky["SEW_DIV_LENGTH"] | |
divNum = 5 | |
if sc.sticky.has_key("SEW_DIV_NUM"): | |
divNum = sc.sticky["SEW_DIV_NUM"] | |
mode = False | |
if sc.sticky.has_key("SEW_DIV_MODE"): | |
mode = sc.sticky["SEW_DIV_MODE"] | |
go = Rhino.Input.Custom.GetOption() | |
go.AcceptNothing(True) | |
strGo = "Edge length is " + str(crvLength) + " Press Enter to accept the current settings." | |
go.SetCommandPrompt(strGo) | |
go.AcceptNumber(True, True) | |
opSize = Rhino.Input.Custom.OptionDouble(dblSize) | |
opNum = Rhino.Input.Custom.OptionInteger(num) | |
opDivLen = Rhino.Input.Custom.OptionDouble(divLen) | |
opDivNum = Rhino.Input.Custom.OptionInteger(divNum) | |
opMode = Rhino.Input.Custom.OptionToggle(mode, "Number", "Length") | |
opAddNum = Rhino.Input.Custom.OptionToggle(addNum, "No", "Yes") | |
go.AddOptionToggle("Mode",opMode) | |
go.AddOptionInteger("CurrentNumber", opNum) | |
go.AddOptionDouble("MarkerSize", opSize) | |
#Decide what division option to add | |
if mode: | |
go.AddOptionDouble("DivisionLength", opDivLen) | |
else: | |
go.AddOptionInteger("DivisionNumber", opDivNum) | |
go.AddOptionToggle("Numbers", opAddNum) | |
result = go.Get() | |
if( go.CommandResult() != Rhino.Commands.Result.Success ): | |
return False, mode,dblSize,num,divLen,divNum, addNum | |
if result == Rhino.Input.GetResult.Number: | |
divNum = int(go.Number()) | |
sc.sticky["SEW_DIV_NUM"] = divNum | |
continue | |
if result == Rhino.Input.GetResult.Nothing: | |
sc.sticky["SEW_START_NUMBER"]= num | |
return True, mode,dblSize,num,divLen,divNum, addNum | |
if result == Rhino.Input.GetResult.Option: | |
mode = opMode.CurrentValue | |
dblSize = opSize.CurrentValue | |
num = opNum.CurrentValue | |
divLen = opDivLen.CurrentValue | |
divNum = opDivNum.CurrentValue | |
addNum = opAddNum.CurrentValue | |
sc.sticky["ADD_SEW_NUMBERS"] = addNum | |
sc.sticky["SEW_NUMBER"] = num | |
sc.sticky["SEW_START_NUMBER"]= num | |
sc.sticky["SEAM_MARKER_SIZE"] = dblSize | |
sc.sticky["SEW_DIV_LENGTH"] = divLen | |
sc.sticky["SEW_DIV_NUM"] = divNum | |
sc.sticky["SEW_DIV_MODE"] = mode | |
continue | |
def EdgeDivider(): | |
pi = math.pi | |
count = 0 | |
startNum = 0 | |
if sc.sticky.has_key("SEW_START_NUMBER"): | |
startNum = sc.sticky["SEW_START_NUMBER"] | |
def PlanarSrfFilter(rhObject, geometry, componentIndex): | |
return geometry.Brep.Surfaces[0].IsPlanar() | |
while count < 2: | |
count +=1 | |
grp = rs.AddGroup() | |
edgeStr = "Select an edge to mark near starting end." | |
if count > 1: | |
edgeStr = "Select the second edge near the starting end." | |
#Get the edge to divide | |
ge = Rhino.Input.Custom.GetObject() | |
ge.GeometryFilter = Rhino.DocObjects.ObjectType.EdgeFilter | |
ge.SetCustomGeometryFilter(PlanarSrfFilter) | |
ge.SetCommandPrompt(edgeStr) | |
rc = ge.Get() | |
if( ge.CommandResult() != Rhino.Commands.Result.Success ): | |
return | |
if rc == Rhino.Input.GetResult.Object: | |
objref = ge.Object(0) | |
pPt = objref.SelectionPoint() | |
e = objref.Geometry() | |
brep = e.Brep | |
face = brep.Faces[0] | |
brepPlane = brep.Surfaces[0].TryGetPlane()[1] | |
eCrv = e.ToNurbsCurve() | |
if count == 1: crvLength = round(eCrv.GetLength(), 3) | |
#Get the options for dividing and marking the edges | |
if count == 1: | |
RC, mode,dblSize,num,divLen,divNum,addNum = GetMarkerOptions(crvLength) | |
if not RC: return | |
if count > 1: | |
if sc.sticky.has_key("SEW_START_NUMBER"): | |
num = sc.sticky["SEW_START_NUMBER"] | |
if not eCrv: return | |
#start counting from the picked end of the curve | |
eDom = eCrv.Domain | |
x = eCrv.ClosestPoint(pPt) | |
if eCrv.ClosestPoint(pPt)[1]>eDom.Mid: | |
eCrv.Reverse() | |
#print "Reversed" | |
#Set the right kind of curve division | |
if mode:#Use length of division | |
pars = eCrv.DivideByLength(divLen, True) | |
else: #Use number of divisions | |
pars = eCrv.DivideByCount(divNum, True) | |
#Intersect a circle with the brep plane to get two points marking the ends of the hash mark | |
for i in range(len(pars)): | |
pt = eCrv.PointAt(pars[i]) | |
rc, plane = eCrv.PerpendicularFrameAt(pars[i]) | |
circle = Rhino.Geometry.Circle(plane, dblSize) | |
ppp = Rhino.Geometry.Intersect.Intersection.CurvePlane(circle.ToNurbsCurve(), brepPlane, .001) | |
p1 = ppp[0].PointA | |
p2 = ppp[1].PointA | |
hashMark = Rhino.Geometry.LineCurve(p1,p2) | |
#if numbering is asked for by the user, get the correct plane etc, and add number-shaped curves. | |
if addNum: #Numbering enabled | |
directionsMatch=False | |
srf = face.DuplicateSurface() | |
if p2.DistanceTo( brep.ClosestPoint(p2)) < .001: | |
vecY = hashMark.TangentAtEnd | |
tPt = p2 | |
else: | |
vecY = hashMark.TangentAtStart | |
vecY.Reverse() | |
tPt = p1 | |
srfRc,parU, parV = srf.ClosestPoint(tPt) | |
planeRc, tPlane = srf.FrameAt(parU, parV) | |
planeAxis = Rhino.Geometry.Vector3d(tPlane.ZAxis) | |
planeAxis.Reverse() | |
vecX= Rhino.Geometry.Vector3d(vecY) | |
vecX.Rotate( pi/2,planeAxis) | |
tPlane = Rhino.Geometry.Plane(tPlane.Origin,vecX,vecY) | |
tPlane.Origin = pt | |
if Rhino.Geometry.Vector3d.VectorAngle(eCrv.TangentAtStart, tPlane.XAxis) < pi/2: | |
directionsMatch=True | |
text = Rhino.Geometry.Curve.CreateTextOutlines(str(num),"Arial", .9*dblSize,0,True,tPlane,.8*dblSize, tolerance=.001) | |
#TEXT = Rhino.Geometry.TextEntity() | |
#TEXT.Plane = tPlane | |
#TEXT.Text = str(num) | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomLeft | |
#TEXT.FontIndex = sc.doc.Fonts.FindOrCreate("Arial",False, False) | |
#sc.doc.Objects.AddText(TEXT) | |
if text: | |
textBB = Rhino.Geometry.BoundingBox() | |
for txtCrv in text: | |
textBB.Union(txtCrv.GetBoundingBox(tPlane)) | |
pass | |
corners = textBB.GetCorners() | |
pToP = Rhino.Geometry.Transform.PlaneToPlane(Rhino.Geometry.Plane.WorldXY,tPlane) | |
for u in range(8): | |
corners[u] = pToP*corners[u] | |
tempPt = corners[1] | |
if directionsMatch: | |
if count > 1: | |
if i > 0: | |
xXform = (pt-corners[1])*1.1 | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomRight | |
else: | |
xXform = None | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomLeft | |
else: | |
if i > 0: | |
xXform = (pt-corners[1])*1.1 | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomRight | |
else: | |
xXform = None | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomLeft | |
else: | |
if count > 1: | |
if i < len(pars)-1: | |
xXform = (pt-corners[1])*1.1 | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomRight | |
else: | |
xXform = None | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomLeft | |
else: | |
if 0< i < len(pars)-1: | |
xXform = None | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomLeft | |
elif i == len(pars)-1 : | |
xXform = None | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomLeft | |
elif i == 0: | |
xXform = (pt-corners[1]).Length*eCrv.TangentAtStart*1.1 | |
#TEXT.Justification= Rhino.Geometry.TextJustification.BottomRight | |
#xXform.Reverse() | |
yXform = tPlane.YAxis*.1*dblSize | |
tempIds = [] | |
#tPlane.Rotate( pi, tPlane.ZAxis) | |
#TEXT.Plane = tPlane | |
#TEXT.Justification= Rhino.Geometry.TextJustification.TopRight | |
#sc.doc.Objects.AddText(TEXT) | |
for txtCrv in text: | |
if xXform is not None: txtCrv.Translate(xXform) | |
txtCrv.Translate(yXform) | |
tempIds.append(sc.doc.Objects.AddCurve(txtCrv)) | |
rs.AddObjectsToGroup(tempIds, rs.AddGroup()) | |
rs.AddObjectsToGroup(tempIds, grp) | |
addId = System.Guid.NewGuid() | |
crvId = sc.doc.Objects.AddCurve(hashMark) | |
rs.AddObjectToGroup(crvId, grp) | |
rs.SetUserText(crvId, "SeamMarkerId", str(addId)) | |
addId = None | |
if addNum: num += 1 | |
sc.sticky["SEW_NUMBER"] = num | |
sc.doc.Objects.UnselectAll() | |
sc.doc.Views.Redraw() | |
sc.sticky["SEW_START_NUMBER"] = num | |
if __name__ == "__main__": EdgeDivider() |
Fixed text placement bugs, added grouping.
Commented out one last reference to 'TEXT' to match the others.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Changed to selecting only edges, and added filter for edges of planar breps