I’m trying to compile my python script into a plugin for Rhino 5 but am running into an issue that I am not able to fix. When I run my script in the Rhino editor it runs fine, although when compiled into a plugin (Im using the Rhinoscript Compiler) the script will not run all the way through. It’s really tough to debug when I cannot see an error like when I do in the editor.
I’ve tried putting print commands in the script to see exactly when it is failing and ive sort of narrowed it down to a line or to but still cannot see when the issue is when the script is running just fine in the editor. Here is a snip of the code where I think I am running into the error:
def BuildComponent(MPoints,EPoints,Degree,Components):
if Components == 1:
Curves = []
for CrossSection in range(len(MPoints)):
Curves.append(RS.AddCurve(MPoints[CrossSection]))
elif Components == 2:
Curves = []
for Count in [0,1]:
for CrossSection in range(len(MPoints[Count])):
Curves.append(RS.AddCurve(MPoints[Count][CrossSection]))
Sections = [RS.AddLoftSrf(Curves,None,None,Degree)]
If there was some way to see the errors python is returning in the rhino command window it would help a lot but I’m sure that there is.
@Steven_Elliott, your code is missing some variables to test it. If the MPoints variable is a list of pointlists, you may start to split this line:
Curves.append(RS.AddCurve(MPoints[CrossSection]))
up into two lines of code so you can check if the curve has been created or not. In case of MPoints variable beeing a nested list of pointlists, i do not understand this line:
Im sorry, maybe I should have been more clear. My script consists of about 1000 lines and this is just a snip of one of the functions defined in the script. The entire thing runs perfectly fine in the rhino editor, but will fail as a plugin.
Is there any syntax discrepancies between a rhino python script and a rhino python script running as a plugin? Or a way to see whats causing the script to fail? I will try splitting up the lines
If Components is == 2, MPoints will consists of 2 lists of points, thats where that comes from
Usually not. The only problems i had prevented compilation but not the script execution, eg. comments at the end of code lines containing invalid chars. Of course if you run a script from the editor and raise exceptions in your code you can see them in the editor once a script completed compared to running it as a plugin.
Hm, if MPoints is a list of pointlists does below line really create a degree 3 curve at your end ?
RS.AddCurve(MPoints[Count][CrossSection])
Imho MPoints[count] will get one of the two pointlists and then accessing [CrossSection] from it will refer to one point in that list. Please try running below in the python editor:
import rhinoscriptsyntax as rs
def DoSome():
A = rs.GetPoints(False, False, "Pick 3 Points (A)", False, 3)
if not A: return
B = rs.GetPoints(False, False, "Pick another 3 Points (B)", False, 3)
if not B: return
# list of pointlists
MPoints = [A,B]
rs.AddCurve(MPoints[0][0])
DoSome()
Is your MPoints variable hosting 2 pointlists as shown above ? I do get an error “Could not convert … to a list of points”. Sorry for asking all these stupid questions, i`m trying to create a running script which i then try to test after compilation. But i would like to use the same structure in the variables you have on your side.
Wow I seperated the lines you mentioned and the plugin worked but then I regenerated the plugin and its failing again! :(.
Anyways if components ==2, think about MPoints as a list of lists of lists. It is like this (working on aircraft model)
Left/Right Wing = list of 2
Cross Sections = list of 5
Point in Cross Sections = list of 15
Coordinates in Point = list of 3
I know my script is tripping on this section as a plugin which is frustrating cause it runs fine as in the editor
edit wow now that I think about it is actually a list of lists of lists of lists… Each point has 3 coordinates… so if I call RS.AddCurve(MPoints[Count][CrossSection]) it will run a line through the 15 points in the specified cross section
Have you deleted the old plugin and re-opened Rhino after compilation ?
if its delicately like this i´d suggest to check if rs.AddCurve actually fails though. If this method fails like in my example above, the function throws an exception which gets printed in the editor but not if the script has been compiled. Btw. How do you recognize that the compiled version of your script does not work ? Is it stopping or doesn`t it create the lofted geometry ?
It’s definitely failing at that command. The only way I can tell is I put a print statement before and after the command and its only printing the first statement then just stopping. But I cant see that error because the script runs fine in the editor.
Yes I’m refreshing rhino and rebuilding/importing the plugin everytime
In the print statement before the command, you may print all the content RS.AddCurve is going to use. Print every point. My guess is that it justs stops because of an exception. RS.AddCurve could throw 3 of them, the first if the pointlist coerciation fails using:
fails, and the third if the curve could not be added to the document. Together with the exception shown above in my script example, there are 4 possible causes for the error.
btw. you might even change RS.AddCurve so it prints errors instead of throwing exceptions. The file is located here:
I dont know. I appreciate the help but am still led nowhere. In the function:
def AddCurve(points, degree=3):
points = rhutil.coerce3dpointlist(points, True)
curve = Rhino.Geometry.Curve.CreateControlPointCurve(points, degree)
if not curve: raise Exception("unable to create control point curve from given points")
rc = scriptcontext.doc.Objects.AddCurve(curve)
if rc==System.Guid.Empty: raise Exception("Unable to add curve to document")
scriptcontext.doc.Views.Redraw()
return rc
its as if the CreateControlPointCurve function is running fine even though there is no curve placed in the interface. Then when its trying to assign an index to the curve it fails because it doesn’t exist.
Why it’s not placing the curve, I cannot find out.
hm, í tested rs.AddCurve extensively and it seems very robust in case of multiple duplicate points or not enough points too. You might create your points as objects before the add curve code or try below snippet after adding the curve:
if not curve.IsValid:
print "Invalid curve detected"
if not isinstance(points, list):
print "No list"
return
for i, p in enumerate(points): rs.AddTextDot(i, p)
return
Wow ok after even more diagnosis ive discovered this which is really strange (thanks by the way I tried what you said). The command will still not work but I have discovered it is not due to the AddCurve command which I thought would be strange in the first place. I think it is something to do with the calling of rhinosyntax, of which that addcurve command just happens to be the first of…
The following DOES cause the plugin to work…
Load the plugin with the script as the command into Rhino.
Open the python editor and run the script.
Undo the command.
Run the command from the plugin.
I think its something like I cannot import rhinosyntax from the plugin but running the script in the editor first will import it for this specific instance of rhino. Heres the inital statement of the script
import rhinoscriptsyntax as RS, math
from decimal import *
global CambConst, FormConst, XCoor, WXOff, WZOff, HTXOff, HTZOff, VTXOff, VTZOff, Scalar, GXOff, GYOff, GZOff
This is all pure guess without seeing the script or having any short repeatable code snippet to test.
btw. why did you use:
import rhinoscriptsyntax as RS, math
instead of:
import rhinoscriptsyntax as rs
import math
and is it required in your script to use the global keyword even if these variables are all declared outside of a function ? Apart from above, from your description it sounds like the script run from the editor will put something into the scope which remains and is then accessed to make the plugin version work. If you run your script then choose from the menu of the python editor:
Tools > Reset Script Engine
then run the compiled script via the plugin, does it fail ? My guess is it does.
Haha sorry I didnt provide any code just because it runs fine when its not in a plugin form so I didnt think itd be much help. I used that line just to save space. Also yes it is because I assign these variables before running any functions. I ran an experiment with this code… same problem:
import rhinoscriptsyntax as RS
RS.AddPoint([0,0,0])
I tried to reset the script engine and it still works. It seems to only fail when a new instance of rhino is opened. TEST.rhp (6 KB)
I uploaded a plugin from the above snipit of code if youd like to try for yourself
Wow these seems like such a minute problem now… but for some reason it just does not like the RS in my rhino. I tried dragging and dropping the plugin and installing it in the plugin manager,
@DanBayn, wasn`t there something reported in relation to opening new files and the option to “reinitialize script engine when opening new files” ? (vb)
I remember some changes @stevebaer made in python which assigned the scriptcontext doc when a new file was opened via batch processing, but cannot find it atm.