Hi @piac
i try Display.DrawDirectionArrow with the script of @dadandroid but i have one problem (i don’t compile the component yet)
when i unplug the curve, the arrows still appear until i hit Test again and i want remove the message box.
from ghpythonlib.componentbase import executingcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
class PreviewEx(component):
def RunScript(self,C):
if not C: return
self.points = []
self.tps = []
self.tgnt = []
pts = rs.DivideCurve(C,2,True)
npts = pts
npts.insert(2, rs.CurveEndPoint(C))
self.points = npts
for i in range(3):
pt = rs.CurveClosestPoint(C,pts[i])
self.tps.append(pt)
tg = rs.CurveTangent(C,self.tps[i])
self.tgnt.append(tg)
def DrawViewportWires(self, args):
try:
for i in range(3):
args.Display.DrawDirectionArrow(self.points[i], self.tgnt[i], System.Drawing.Color.White)
except Exception, e:
None
#System.Windows.Forms.MessageBox.Show(str(e), "script error")
def IsPreviewCapable(self):
return True
Thanks Giulio
i tried but i don’t understand exactly, if i use
def DrawViewportWires(self, args):
if not C: return
for i in range(3):
args.Display.DrawDirectionArrow(self.points[i], self.tgnt[i], System.Drawing.Color.White)
The line disappear from the viewoprt.
The only method work for me now when i disable the condition, with error on the component
I can fix it for you, but it would be wiser for you to study it also line by line, to see what it does. If you are OK with this, I’ll move it to a new topic. This is an advanced topic, and it might just be a bit overwhelming if you are just starting with scripting.
i call it self.crv = C instead of C and it work fine
from ghpythonlib.componentbase import executingcomponent as component
#import Grasshopper, GhPython
import System
#import Rhino
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
class PreviewEx(component):
def RunScript(self,C):
self.crv = C
if not self.crv: return
self.points = []
self.tps = []
self.tgnt = []
pts = rs.DivideCurve(self.crv,2,True)
npts = pts
npts.insert(2, rs.CurveEndPoint(self.crv))
self.points = npts
for i in range(3):
pt = rs.CurveClosestPoint(self.crv,pts[i])
self.tps.append(pt)
tg = rs.CurveTangent(self.crv,self.tps[i])
self.tgnt.append(tg)
def DrawViewportWires(self,arg):
if not self.crv: return
for i in range(3):
arg.Display.DrawDirectionArrow(self.points[i], self.tgnt[i], System.Drawing.Color.White)
Yes i just start scripting with grasshopper, i hope see your solution to learn from it and for anyone who need help in future
the script created based on script of David in this thread as i mentioned before
I haven’t tested the script, but it also needs to compute the bounding box of all the geometry that it wants to preview. Then, the bounding box must be returned in the get_ClippingBox method. As it is shown here:
from ghpythonlib.componentbase import executingcomponent as component
import System
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
class PreviewEx(component):
def RunScript(self,C):
self.crv = C
if not self.crv: return
self.points = []
self.tgnt = []
for i in range(len(C)):
pts = rs.DivideCurve(self.crv[i],2,True)
for j in range(3):
pt = rs.CurveClosestPoint(self.crv[i],pts[j])
tg = rs.CurveTangent(self.crv[i],pt)
self.tgnt.append(tg)
self.points.append(pts[j])
#print self.points
#print self.tgnt
def DrawViewportWires(self,arg):
if not self.crv: return
for i in range(len(self.crv)):
for i in range(3):
arg.Display.DrawDirectionArrow(self.points[i], self.tgnt[i], System.Drawing.Color.White)
the input have two curves (or more )
in def DrawViewportWires(self,arg): the length of curves list have no effect
maybe because i append all points and tangents
One day it might not work fine. This is a requirement that does not show sometimes. But then when it shows, it is really bad. I also don’t see the point of compiling if the code is already online…
My 2 cents.
I compile it to try if it work because sometimes the scripts it work fine but after compiling nope.
and of course i need the best solution that why i asked and i don’t really understand the idea of the bounding box, i will study it more.
I use always examples from help but some of them don’t work or need more lines to work
The bounding box computation is because of this: Rhino tries to optimize preview by using bounding boxes. If the thing that you want to draw is outside the “view frustum”, then its drawing function will not be called. This operation is called “view frustum culling”.
from ghpythonlib.componentbase import executingcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
class DisplayDirection(component):
def __init__(self):
self.pts = []
self.bb = Rhino.Geometry.BoundingBox()
def RunScript(self,C):
self.c = C
if not self.c: return
self.bb = Rhino.Geometry.BoundingBox()
self.tps = []
self.tgnt = []
self.pts = rs.DivideCurve(self.c,2,True)
for i in range(len(self.pts)):
self.bb.Union(self.pts[i])
self.pts.insert(2, rs.CurveEndPoint(self.c))
for i in range(3):
pt = rs.CurveClosestPoint(self.c,self.pts[i])
self.tps.append(pt)
tg = rs.CurveTangent(self.c,self.tps[i])
self.tgnt.append(tg)
def DrawViewportWires(self,arg):
if not self.c: return
for i in range(3):
arg.Display.DrawDirectionArrow(self.pts[i], self.tgnt[i], System.Drawing.Color.White)
def get_ClippingBox(self):
return self.bb
Update: this version work with multi curves, i also add the idea of bounding box
i know there is always more simple method but that what i get
from ghpythonlib.componentbase import executingcomponent as component
import Grasshopper, GhPython
import System
import Rhino
import rhinoscriptsyntax as rs
class CurvesDirection(component):
def __init__(self):
self.pts = []
self.bb = Rhino.Geometry.BoundingBox()
def RunScript(self, C):
self.c = C
if not self.c: return
self.bb = Rhino.Geometry.BoundingBox()
lisc = []
self.plist = []
self.tlist = []
for i in range(len(self.c)):
lisc.append([self.c[i]])
for i in range(len(self.c)):
if not self.c[i] : return
if rs.IsCurveClosed(self.c[i]) == True:
n = 3
elif rs.IsCurveClosed(self.c[i]) == False:
n = 2
for j in range(1):
self.pt = rs.DivideCurve(lisc[i][0],n,True)
for k in range(len(self.pt)):
self.bb.Union(self.pt[k])
self.pts = rs.CurveClosestPoint(self.c[i],self.pt[k])
self.tg = rs.CurveTangent(self.c[i],self.pts)
self.plist.append(self.pt[k])
self.tlist.append(self.tg)
parts = len(self.c)
self.p = [self.plist[(i*len(self.plist))//parts:((i+1)*len(self.plist))//parts] for i in range(parts)]
self.t = [self.tlist[(i*len(self.plist))//parts:((i+1)*len(self.plist))//parts] for i in range(parts)]
def DrawViewportWires(self,arg):
if not self.c: return
for i in range(len(self.c)):
if not self.c[i] : return
for j in range(3):
arg.Display.DrawDirectionArrow(self.p[i][j],self.t[i][j], System.Drawing.Color.White)
def get_ClippingBox(self):
return self.bb