both my plotter/cutter and wide format printer. I had been running the plotter from my main work laptop - a Win10 machine via the plotters USB port. As it turns out you can't get Win XP drivers for this USB connection so I needed another solution.
I tried to use the plotters DB25 serial port connection using an old DB9 to DB25 modem cable I had in my collection = no luck the plotter wouldn't talk. A bit more research and it turns out these plotters need a 'null modem' cross over cable to operate. I found a pic of the correct wiring online and made up my own with some cable and connectors from the local electronics hobby shop.
With this hooked up and using Hyperterminal I was able to fire some codes to the plotter directly and get a response back - winning!
At this point I got my original code working with the 'net use' redirect from LPT1 to COM1.
HOWEVER - being that the plotter was now on a COM port there are a few more interesting things you can do with it - one is being able to read the paper size/cut area from the printer.
So what I needed to to was find a way to send and receive data to/from the plotter using the serial port.
A bit of research into .NET's serial port interface and using a bunch of small pieces of test code I have manged to completely re-jig this driver.
Upgrades include:
- Direct Serial Port comms using Null Modem cable (a USB to serial adaptor + null modem should also work)
- Plot area read from the plotter - a rectangle the size of the plot area is placed on a separate layer and coloured red
- Testing to see if selected plotting curves are both closed and inside of the cutting area - with errors shown and exiting if they are not right.
- After plot 'parking' of the plot head at the end of the cut items + an adjustable offset (currently requires manual resetting of origin on the plotter before for next cut)
Great thing is it is now 100% running within Rhino Python - no DOS command line calls = no flashing up of the CMD wind. Also no temp files needed on the HDD and no limit to number of curves that can be plotted - tested with 200 or so with no issues.
Overall very happy with whole project - have learnt a LOT about Python and .NET interfacing AND ended up with a very handy/useful tool.
Cheers
DK
# This code is a WIP # It plots directly to a DGI Plotter# via the serial port
import System.IO.Ports as Portsimport rhinoscriptsyntax as rsimport time
#Some setup valuescom_port = 'COM1' #change to match plotter port baud_rate = 9600 #change to match plotter settingplotter_step = .025 #mmfinsh_offset = 10 #mm
#Delete old cutting area and cut objectsif rs.IsLayer('Cutting Area'): rs.PurgeLayer('Cutting Area')if rs.IsLayer('Cutting Objects'): rs.PurgeLayer('Cut Objects')
#Setup Serial PortMyport = Ports.SerialPort(com_port)Port_Write = Ports.SerialPort.WriteMyport.BaudRate = baud_rateMyport.ReadTimeout=5000 #5 secsMyport.Close()Myport.Open()
#Setup PlotterPort_Write(Myport, 'PU;PA0,0;IN;\n')Port_Write(Myport, 'SP1;\n')Port_Write(Myport, 'PA;\n')time.sleep(2)
#Read the Paper size from PlotterPort_Write(Myport, 'OH;') #HPGL read limits codetime.sleep(2)
return1 = ''papersize = ''count = 0char_in_buffer = 0chars_in_buffer = Ports.SerialPort.BytesToRead.GetValue(Myport)
if chars_in_buffer == 0: print 'Plotter not ready' Myport.Close() exit()
while (count < chars_in_buffer): return1 = Myport.ReadChar() papersize = papersize + chr(return1) count = count + 1
papersize = papersize.split(",")rect1 = (float(papersize[2])*plotter_step)rect2 = (float(papersize[3])*plotter_step)
print 'Cutting area = ' + str(rect1) + 'x' + str(rect2)
#place cutting area curve on its own layer, make it red and lock itplane = rs.WorldXYPlane()cutting_area = rs.AddRectangle( plane, (rect1), (rect2))rs.AddLayer (name='Cutting Area', color=(255,0,0), visible=True, locked=True, parent=None)rs.ObjectLayer(cutting_area, 'Cutting Area')
#get plotting objects
allCurves = rs.GetObjects("Select curves to plot", rs.filter.curve)
#test to see if these are closed curves - exit if not
for curve in allCurves: test_closed = rs.IsCurveClosed(curve) if test_closed == 0: print "One or move of these curves are not closed" Myport.Close() exit()
#test to see if these are inside cutting area - exit if not
for curve in allCurves: test_inside = rs.PlanarClosedCurveContainment(curve, cutting_area)
if test_inside==0 or test_inside==1: print "One or more of these curves are outside of cut area" Myport.Close() exit()
#All ok - convert to points and send data to printer
rs.AddLayer (name='Cut Objects', color=(0,255,0), visible=False, locked=True, parent=None)
for curve in allCurves: Port_Write(Myport, 'PU;PA;SP1;\n') polyline = rs.ConvertCurveToPolyline(curve,angle_tolerance=5.0, tolerance=0.025, delete_input=False, min_edge_length=0, max_edge_length=0) points = rs.CurveEditPoints(polyline) rs.ObjectLayer(polyline, 'Cut Objects')
# PU to the first point x = points[0][0] y = points[0][1] Port_Write(Myport, 'PU' + str(int(x / plotter_step)) + ',' + str(int(y / plotter_step)) + ';\n') # PD to every subsequent point i = 1 while i < len(points): x = points[i][0] y = points[i][1] Port_Write(Myport, 'PD' + str(int(x / plotter_step)) + ',' + str(int(y / plotter_step)) + ';\n') i += 1
Port_Write(Myport,'PU;\n')
#find the far end of the cutbox = rs.BoundingBox(allCurves)far_end = str(box[1])far_end = far_end.split(",")far_end = far_end[0]far_end = float(far_end)/plotter_stepfar_end = (int(far_end))+ finsh_offsetfar_end = str(far_end)print (far_end)
#return plotter home and close portPort_Write(Myport, 'PU;PA' + far_end + ',0;IN;\n')Port_Write(Myport, 'SP1;\n')Port_Write(Myport, 'PA;\n')Myport.Close()time.sleep(10)…
Window menu).
● String matching algorithm rewritten in an attempt to improve Popup search fidelity.
● Windows linked to the Grasshopper main window will no longer be repositioned when Ctrl is down.
● The Extend Curve component now accepts negative lengths in order to trim the curve.
● Added Fit Line to Points component (Curve.Primitive dropdown)
● Added Fit Circle to Points component (Curve.Primitive dropdown)
● AutoSave file format is now customizable through the new Settings interface.
● Mouse scroll wheel can now be used to adjust slider controls (not Number Slider objects).
● Added tooltips to the Popup Search box.
● Added Info Mode to the Canvas (hold Ctrl+Alt and click on an object).
● Added initialization code to the Cull Nth component.
● Added initialization code to the Cull Index component.
● Added initialization code to the Random Reduce component.
● Added initialization code to the Duplicate component.
● Added initialization code to the List Item component.
● Added initialization code to the Repeat Data component.
● Added initialization code to the Shift List component.
● Added initialization code to the Split List component.
● Added initialization code to the Sequence component.
● Added initialization code to the Constant E component.
● Added initialization code to the Constant Epsilon component.
● Added initialization code to the Factorial component.
● Added initialization code to the Fibonacci component.
● Added initialization code to the Golden Ratio component.
● Added initialization code to the Constant Pi component.
● Added initialization code to the Random component.
● Added initialization code to the Range component.
● Added initialization code to the Series component.
● Added initialization code to the Square component.
● Added initialization code to the Square Root component.
● Added initialization code to the Cube component.
● Added initialization code to the Cube Root component.
● Added initialization code to the Log10 component.
● Added initialization code to the Log component.
● Added initialization code to the Exponent component.
● Added initialization code to the Power of 2 component.
● Added initialization code to the Power of 10 component.
● Added initialization code to the Sine component.
● Added initialization code to the Sinc component.
● Added initialization code to the Cosine component.
● Added initialization code to the Tangent component.
● Added initialization code to the ArcSine component.
● Added initialization code to the ArcCosine component.
● Added initialization code to the ArcTangent component.
● Added initialization code to the Secant component.
● Added initialization code to the Cosecant component.
● Added initialization code to the Cotangent component.
● Added initialization code to the One over X component.
● Added initialization code to the Absolute component.
● Added initialization code to the Sign component.
● Added initialization code to the ToDegrees component.
● Added initialization code to the ToRadians component.
● Added initialization code to the N-Base log component.
● Added initialization code to the Smaller Than component.
● Added initialization code to the Larger Than component.
● Added initialization code to the Equal To component.
● Added initialization code to the Similar To component.
● Added initialization code to the Addition component.
● Added initialization code to the Subtraction component.
● Added initialization code to the Multiplication component.
● Added initialization code to the Division component.
● Added initialization code to the Integer Division component.
● Added initialization code to the Minimum component.
● Added initialization code to the Maximum component.
● Added initialization code to the Modulus component.
● Added initialization code to the Power component.
● Added initialization code to the Concatenate component.
● Added initialization code to the String Split component.
● Added initialization code to the String Join component.
● Added initialization code to the Evaluate Length component.
● Added initialization code to the Circle component.
● Added initialization code to the Circle CNR component.
● Added initialization code to the Arc component.
● Added initialization code to the Curve component.
● Added initialization code to the Interpolated Curve component.
● Added initialization code to the Offset Curve component.
● Added initialization code to the Offset Curve Loose component.
● Added initialization code to the Offset Curve On Surface component.
● Added initialization code to the Extend Curve component.
● Added initialization code to the Catenary component.
● Added initialization code to the Line SDL component.
● Added initialization code to the Fillet component.
● Added initialization code to the Fillet Distance component.
● Added initialization code to the Move component.
● Added initialization code to the Scale component.
● Added initialization code to the Mesh Plane component.
● Added initialization code to the Mesh Box component.
● Added initialization code to the Mesh Sphere component.
● Added initialization code to the Sphere component.
● Added initialization code to the Surface Offset component.
● Added initialization code to the Surface Offset Loose component.
● Added initialization code to the Divide Curve component.
● Added initialization code to the Divide Curve Length component.
● Added initialization code to the Divide Curve Distance component.
● Added initialization code to the Curve Frames component.
● Added initialization code to the Curve Perpendicular Frames component.
● Added initialization code to the Square Grid component.
● Added initialization code to the Rectangular Grid component.
● Added initialization code to the Vector Amplitude component.
○ Sliders would cause too many solve events when controlled externally, this is fixed.
○ The Canvas went black when Galapagos was in fast display modes, this is fixed.
○ AutoSave documents are now deleted when the document is closed from the MDI menu.
I'll be gone for a month, but I'm sure I'll be able to check with the forum every now and again.
--
David Rutten
david@mcneel.com
Poprad, Slovakia…
be done easier, but later on the geometry will change and therefore this seems the better option. But coming back to the problem
First, there were some problems concerning the zone, although it seems solved still the “runenergysimulation” gives the following warning:
1. The simulation has not run correctly because of this severe error:
** Severe ** UpdateZoneSizing: Cooling supply air temperature (calculated) within 2C of zone temperature
Do one of you know what went wrong? It probably will solve most of it.
Second, “set Zone Thresholds” gives the following warning:
1. Solution exception:global name 'maxHumidity_' is not defined
However, the component is missing the max humidity input on the list, has this to do something with the error?
All the components are up to date.
I hope it will be an easy fix.
Gr Lars
“set Zone Thresholds” runtime error
{0;0;0}0. Runtime error (UnboundNameException): global name 'maxHumidity_' is not defined1. Traceback: line 80, in checkTheInputs, "<string>" line 282, in script
"runenergysimulation” report
{0;0}0. Current document units is in Meters1. Conversion to Meters will be applied = 1.0002. TypeError('Waarde kan niet null zijn.\r\nParameternaam: source',)3. Failed to copy the object. Returning the original objects...This can cause strange behaviour!4. [1 of 8] Writing simulation parameters...5. [2 of 8] No context surfaces...6. [3 of 8] Writing geometry...7. [4 of 8] Writing Electric Load Center - Generator specifications ...8. [5 of 8] Writing materials and constructions...9. [6 of 8] Writing schedules...10. [7 of 8] Writing loads and ideal air system...11. [8 of 8] Writing outputs...12. ...... idf file is successfully written to : c:\ladybug\unnamed\EnergyPlus\unnamed.idf13. 14. Analysis is running!...15. c:\ladybug\unnamed\EnergyPlus\eplusout.csv16. ......
Done! Read below for errors and warnings:
17. 18. Program Version,EnergyPlus, Version 8.3.0-6d97d074ea, YMD=2016.03.02 20:55,IDD_Version 8.3.019. 20. ** Warning ** IP: Note -- Some missing fields have been filled with defaults. See the audit output file for details.21. 22. ************* Beginning Zone Sizing Calculations23. 24. ** Warning ** GetInternalHeatGains: People="CLASSROOMOFFICEPEOPLE", Activity Level Schedule Name values25. 26. ** ~~~ ** fall outside typical range [70,1000] W/person for Thermal Comfort Reporting.27. 28. ** ~~~ ** Odd comfort values may result; Schedule="SCHOCCUPANCYSCHEDULE".29. 30. ** ~~~ ** Entered min/max range=[0.0,1.0] W/person.31. 32. ** Warning ** Calculated design heating load for zone=CLASSROOM is zero.33. 34. ** ~~~ ** Check Sizing:Zone and ZoneControl:Thermostat inputs.35. 36. ** Severe ** UpdateZoneSizing: Cooling supply air temperature (calculated) within 2C of zone temperature37. 38. ** ~~~ ** ...check zone thermostat set point and design supply air temperatures39. 40. ** ~~~ ** ...zone name = CLASSROOM41. 42. ** ~~~ ** ...design sensible cooling load = 25499.10 W43. 44. ** ~~~ ** ...thermostat set point temp = 0.000 C45. 46. ** ~~~ ** ...zone temperature = 15.334 C47. 48. ** ~~~ ** ...supply air temperature = 15.000 C49. 50. ** ~~~ ** ...temperature difference = -0.33433 C51. 52. ** ~~~ ** ...calculated volume flow rate = 197273.21341 m3/s53. 54. ** ~~~ ** ...calculated mass flow rate = 237634.19357 kg/s55. 56. ** Warning ** ManageSizing: For a plant sizing run, there must be at least 1 Sizing:Plant object input. SimulationControl Plant Sizing option ignored.57. 58. ************* Testing Individual Branch Integrity59. 60. ************* All Branches passed integrity testing61. 62. ************* Testing Individual Supply Air Path Integrity63. 64. ************* All Supply Air Paths passed integrity testing65. 66. ************* Testing Individual Return Air Path Integrity67. 68. ************* All Return Air Paths passed integrity testing69. 70. ************* No node connection errors were found.71. 72. ************* Beginning Simulation73. 74. ************* Simulation Error Summary *************75. 76. ** Warning ** The following Report Variables were requested but not generated77. 78. ** ~~~ ** because IDF did not contain these elements or misspelled variable name -- check .rdd file79. 80. ************* Key=*, VarName=ZONE PACKAGED TERMINAL HEAT PUMP TOTAL COOLING ENERGY, Frequency=Hourly81. 82. ************* Key=*, VarName=ZONE PACKAGED TERMINAL HEAT PUMP TOTAL HEATING ENERGY, Frequency=Hourly83. 84. ************* Key=*, VarName=CHILLER ELECTRIC ENERGY, Frequency=Hourly85. 86. ************* Key=*, VarName=BOILER HEATING ENERGY, Frequency=Hourly87. 88. ************* Key=*, VarName=FAN ELECTRIC ENERGY, Frequency=Hourly89. 90. ************* Key=*, VarName=ZONE VENTILATION FAN ELECTRIC ENERGY, Frequency=Hourly91. 92. ************* Key=*, VarName=EARTH TUBE FAN ELECTRIC ENERGY, Frequency=Hourly93. 94. ************* Key=*, VarName=PUMP ELECTRIC ENERGY, Frequency=Hourly95. 96. ************* Key=*, VarName=ZONE VENTILATION TOTAL HEAT LOSS ENERGY, Frequency=Hourly97. 98. ************* Key=*, VarName=ZONE VENTILATION TOTAL HEAT GAIN ENERGY, Frequency=Hourly99. 100. ************* Key=*, VarName=EARTH TUBE ZONE SENSIBLE COOLING ENERGY, Frequency=Hourly101. 102. ************* Key=*, VarName=EARTH TUBE ZONE SENSIBLE HEATING ENERGY, Frequency=Hourly103. 104. ************* EnergyPlus Warmup Error Summary. During Warmup: 0 Warning; 0 Severe Errors.105. 106. ************* EnergyPlus Sizing Error Summary. During Sizing: 3 Warning; 1 Severe Errors.107. 108. ************* EnergyPlus Completed Successfully-- 5 Warning; 1 Severe Errors; Elapsed Time=00hr 00min 4.65sec109.…
R_HOST=tcp://192.168.99.100:2376&SET DOCKER_CERT_PATH=C:\Users\akiwya\.docker\machine\machines\default&SET DOCKER_MACHINE_NAME=default&docker exec -i 4c9bb2f7444b pgrep snappyHexMesh SET DOCKER_TLS_VERIFY=1&SET DOCKER_HOST=tcp://192.168.99.100:2376&SET DOCKER_CERT_PATH=C:\Users\akiwya\.docker\machine\machines\default&SET DOCKER_MACHINE_NAME=default&docker exec -i 4c9bb2f7444b pgrep snappyHexMesh SET DOCKER_TLS_VERIFY=1&SET DOCKER_HOST=tcp://192.168.99.100:2376&SET DOCKER_CERT_PATH=C:\Users\akiwya\.docker\machine\machines\default&SET DOCKER_MACHINE_NAME=default&docker exec -i 4c9bb2f7444b pgrep snappyHexMesh SET DOCKER_TLS_VERIFY=1&SET DOCKER_HOST=tcp://192.168.99.100:2376&SET DOCKER_CERT_PATH=C:\Users\akiwya\.docker\machine\machines\default&SET DOCKER_MACHINE_NAME=default&docker exec -i 4c9bb2f7444b pgrep snappyHexMesh SET DOCKER_TLS_VERIFY=1&SET DOCKER_HOST=tcp://192.168.99.100:2376&SET DOCKER_CERT_PATH=C:\Users\akiwya\.docker\machine\machines\default&SET DOCKER_MACHINE_NAME=default&docker exec -i 4c9bb2f7444b pgrep snappyHexMesh SET DOCKER_TLS_VERIFY=1&SET DOCKER_HOST=tcp://192.168.99.100:2376&SET DOCKER_CERT_PATH=C:\Users\akiwya\.docker\machine\machines\default&SET DOCKER_MACHINE_NAME=default&docker exec -i 4c9bb2f7444b pgrep snappyHexMesh Butterfly is running blockMesh. PID: 1837 SET DOCKER_TLS_VERIFY=1&SET DOCKER_HOST=tcp://192.168.99.100:2376&SET DOCKER_CERT_PATH=C:\Users\akiwya\.docker\machine\machines\default&SET DOCKER_MACHINE_NAME=default&docker exec -i 4c9bb2f7444b pgrep snappyHexMesh
/*---------------------------------------------------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: v1612+ | | \\ / A nd | Web: www.OpenFOAM.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ Build : v1612+ Exec : blockMesh Date : May 22 2017 Time : 08:51:50 Host : "default" PID : 1837 Case : /home/ofuser/workingDir/butterfly/outdoor_airflow nProcs : 1 sigFpe : Enabling floating point exception trapping (FOAM_SIGFPE). fileModificationChecking : Monitoring run-time modified files using timeStampMaster (fileModificationSkew 10) allowSystemOperations : Allowing user-supplied system call operations
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Create time
Creating block mesh from "/home/ofuser/workingDir/butterfly/outdoor_airflow/system/blockMeshDict" Creating block edges No non-planar block faces defined Creating topology blocks Creating topology patches
Creating block mesh topology
Check topology
Basic statistics Number of internal faces : 0 Number of boundary faces : 6 Number of defined boundary faces : 6 Number of undefined boundary faces : 0 Checking patch -> block consistency
Creating block offsets Creating merge list .
Creating polyMesh from blockMesh Creating patches Creating cells new cannot satisfy memory request. This does not necessarily mean you have run out of virtual memory. It could be due to a stack violation caused by e.g. bad use of pointers or an out of date shared library Runtime error (PythonException):
Butterfly failed to run OpenFOAM command! new cannot satisfy memory request. This does not necessarily mean you have run out of virtual memory. It could be due to a stack violation caused by e.g. bad use of pointers or an out of date shared library Traceback: line 51, in script
I don't really have any knowledge in CFD simulation and only watched the tutorials and managed to get the sample files to work. So this time, I replaced the starting geometry my building which is a curve building, I wonder if that is the issue that caused this problem. Can anyone enlighten me on the issue?
Warm regards,
Annie…
he "return" is comment out as shown below?
After restarting Rhino and Grasshopper, I opened the outdoors_airflow demo file, and the first step of creating the case file is ok:
Then the blockMesh component gives the following error: seems I have to manually start OF first..
so, as the error message suggested, I open OF by Start_OF.bat:
Then come back to the blockMesh component, now it can be executed while the OF command line window is also openning:
... and the blockMesh finished successfully:
... so I proceeded to run snappyHexMesh, checkMesh and update fvScheme:
... up to the simpleFoam component, I got the error again:
The warning message is:
1. Solution exception: --> OpenFOAM command Failed!#0 Foam::error::printStack(Foam::Ostream&) in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libOpenFOAM.so" #1 Foam::sigFpe::sigHandler(int) in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libOpenFOAM.so" #2 ? in "/lib64/libc.so.6" #3 double Foam::sumProd<double>(Foam::UList<double> const&, Foam::UList<double> const&) in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libOpenFOAM.so" #4 Foam::PCG::solve(Foam::Field<double>&, Foam::Field<double> const&, unsigned char) const in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libOpenFOAM.so" #5 Foam::GAMGSolver::solveCoarsestLevel(Foam::Field<double>&, Foam::Field<double> const&) const in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libOpenFOAM.so" #6 Foam::GAMGSolver::Vcycle(Foam::PtrList<Foam::lduMatrix::smoother> const&, Foam::Field<double>&, Foam::Field<double> const&, Foam::Field<double>&, Foam::Field<double>&, Foam::Field<double>&, Foam::Field<double>&, Foam::Field<double>&, Foam::PtrList<Foam::Field<double> >&, Foam::PtrList<Foam::Field<double> >&, unsigned char) const in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libOpenFOAM.so" #7 Foam::GAMGSolver::solve(Foam::Field<double>&, Foam::Field<double> const&, unsigned char) const in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libOpenFOAM.so" #8 Foam::fvMatrix<double>::solveSegregated(Foam::dictionary const&) in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/lib/libfiniteVolume.so" #9 Foam::fvMatrix<double>::solve(Foam::dictionary const&) in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/bin/simpleFoam" #10 Foam::fvMatrix<double>::solve() in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/bin/simpleFoam" #11 ? in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/bin/simpleFoam" #12 __libc_start_main in "/lib64/libc.so.6" #13 ? in "/opt/OpenFOAM/OpenFOAM-v1606+/platforms/linux64GccDPInt32Opt/bin/simpleFoam"
... and the command lines in the readMe! output are pretty long and it is saved in the text file attached here.
So, my questions are:
1. why I have to manually start OF first before I can use the blockMesh component? Should butterfly automatically start OF?
2. what might be the cause of the unsuccessful run of simpleFoam in the end?
Hope you can kindly advise! Thank you!
- Ji
…
rmation?" I know that this can already be accomplished using the brilliant Kangaroo plugin, but I wanted a simpler and faster (yet still accurate) single component that could replicate this unique curve using a variety of inputs: the length of the rod/wire, the width/distance between the endpoints, the height of the bend, and the tangent angle at the start. I also wanted make the unknowns (such as height if only length and width are known) easily accessible for plugging into additional components.
The resulting script, being an all-in-one solution, is somewhat unwieldy, but it could easily be broken down into smaller components (custom .gha's which I don't have the ability to code). If someone wants to tackle this, please do! I'm not an expert coder by any means, and as this was only my second time diving into Grasshopper scripting, if the script seems somewhat strange, that's probably why. I did try to comment the code pretty well though. Here's the full description:
--------------------------------------------------
DESCRIPTION: This beast creates the so-called 'elastica curve', the shape a long, thin rod or wire makes when it is bent elastically (i.e. not permanently). In this case, force is assumed to only be applied horizontally (which would be in line with the rod at rest) and both ends are assumed to be pinned or hinged meaning they are free to rotate (as opposed to clamped, when the end tangent angle is fixed, usually horizontally). An interesting finding is that it doesn't matter what the material or cross-sectional area is, as long as they're uniform along the entire length. Everything makes the same shape when bent as long as it doesn't cross the threshold from elastic to plastic (permanent) deformation (I don't bother to find that limit here, but can be found if the yield stress for a material is known).
Key to the formulas used in this script are elliptic integrals, specifically K(m), the complete elliptic integral of the first kind, and E(m), the complete elliptic integral of the second kind. There was a lot of confusion over the 'm' and 'k' parameters for these functions, as some people use them interchangeably, but they are not the same. m = k^2 (thus k = Sqrt(m)). I try to use the 'm' parameter exclusively to avoid this confusion. Note that there is a unique 'm' parameter for every configuration/shape of the elastica curve.
This script tries to find that unique 'm' parameter based on the inputs. The algorithm starts with a test version of m, evaluates an expression, say 2*E(m)/K(m)-1, then compares the result to what it should be (in this case, a known width/length ratio). Iterate until the correct m is found. Once we have m, we can then calculate all of the other unknowns, then find points that lie on that curve, then interpolate those points for the actual curve. You can also use Wolfram|Alpha as I did to find the m parameter based on the equations in this script (example here: http://tiny.cc/t4tpbx for when say width=45.2 and length=67.1).
Other notes:
* This script works with negative values for width, which will creat a self-intersecting curve (as it should). The curvature of the elastica starts to break down around m=0.95 (~154°), but this script will continue to work until M_MAX, m=0.993 (~169°). If you wish to ignore self-intersecting curves, set ignoreSelfIntersecting to True
* When the only known values are length and height, it is actually possible for certain ratios of height to length to have two valid m values (thus 2 possible widths and angles). This script will return them both.
* Only the first two valid parameters (of the required ones) will be used, meaning if all four are connected (length, width or a PtB, height, and angle), this script will only use length and width (or a PtB).
* Depending on the magnitude of your inputs (say if they're really small, like if length < 10), you might have to increase the constant ROUNDTO at the bottom
REFERENCES: {1} "The elastic rod" by M.E. Pacheco Q. & E. Pina, http://www.scielo.org.mx/pdf/rmfe/v53n2/v53n2a8.pdf {2} "An experiment in nonlinear beam theory" by A. Valiente, http://www.deepdyve.com/lp/doc/I3lwnxdfGz {3} "Snap buckling, writhing and Loop formation In twisted rods" by V.G.A. GOSS, http://myweb.lsbu.ac.uk/~gossga/thesisFinal.pdf {4} "Theory of Elastic Stability" by Stephen Timoshenko, http://www.scribd.com/doc/50402462/Timoshenko-Theory-of-Elastic-Stability (start on p. 76)
INPUT: PtA - First anchor point (required) PtB - Second anchor point (optional, though 2 out of the 4--length, width, height, angle--need to be specified) [note that PtB can be the same as PtA (meaning width would be zero)] [also note that if a different width is additionally specified that's not equal to the distance between PtA and PtB, then the end point will not equal PtB anymore] Pln - Plane of the bent rod/wire, which bends up in the +y direction. The line between PtA and PtB (if specified) must be parallel to the x-axis of this plane
** 2 of the following 4 need to be specified ** Len - Length of the rod/wire, which needs to be > 0 Wid - Width between the endpoints of the curve [note: if PtB is specified in addition, and distance between PtA and PtB <> width, the end point will be relocated Ht - Height of the bent rod/wire (when negative, curve will bend downward, relative to the input plane, instead) Ang - Inner departure angle or tangent angle (in radians) at the ends of the bent rod/wire. Set up so as width approaches length (thus height approaches zero), angle approaches zero
* Following variables only needed for optional calculating of bending force, not for shape of curve. E - Young's modulus (modulus of elasticity) in GPa (=N/m^2) (material-specific. for example, 7075 aluminum is roughly 71.7 GPa) I - Second moment of area (or area moment of inertia) in m^4 (cross-section-specific. for example, a hollow rod would have I = pi * (outer_diameter^4 - inner_diameter^4) / 32 Note: E*I is also known as flexural rigidity or bending stiffness
OUTPUT: out - only for debugging messages Pts - the list of points that approximate the shape of the elastica Crv - the 3rd-degree curve interpolated from those points (with accurate start & end tangents) L - the length of the rod/wire W - the distance (width) between the endpoints of the rod/wire H - the height of the bent rod/wire A - the tangent angle at the (start) end of the rod/wire F - the force needed to hold the rod/wire in a specific shape (based on the material properties & cross-section) **be sure your units for 'I' match your units for the rest of your inputs (length, width, etc.). Also note that the critical buckling load (force) that makes the rod/wire start to bend can be found at height=0
THANKS TO: Mårten Nettelbladt (thegeometryofbending.blogspot.com) Daniel Piker (Kangaroo plugin) David Rutten (Grasshopper guru) Euler & Bernoulli (the O.G.'s)
--------------------------------------------------
Edit: More on the math behind this here.
Cheers,
Will
…
Added by Will McElwain at 4:08pm on February 26, 2014
n, so if you want Strings, be sure to encase them in double quotes:
Concat = " alcohol doesn't affect me"
● Added initialization code to the Cull Nth component.
● Added initialization code to the Cull Index component.
● Added initialization code to the Random Reduce component.
● Added initialization code to the Duplicate component.
● Added initialization code to the List Item component.
● Added initialization code to the Repeat Data component.
● Added initialization code to the Shift List component.
● Added initialization code to the Split List component.
● Added initialization code to the Sequence component.
● Added initialization code to the Constant E component.
● Added initialization code to the Constant Epsilon component.
● Added initialization code to the Factorial component.
● Added initialization code to the Fibonacci component.
● Added initialization code to the Golden Ratio component.
● Added initialization code to the Constant Pi component.
● Added initialization code to the Random component.
● Added initialization code to the Range component.
● Added initialization code to the Series component.
● Added initialization code to the Square component.
● Added initialization code to the Square Root component.
● Added initialization code to the Cube component.
● Added initialization code to the Cube Root component.
● Added initialization code to the Log10 component.
● Added initialization code to the Log component.
● Added initialization code to the Exponent component.
● Added initialization code to the Power of 2 component.
● Added initialization code to the Power of 10 component.
● Added initialization code to the Sine component.
● Added initialization code to the Sinc component.
● Added initialization code to the Cosine component.
● Added initialization code to the Tangent component.
● Added initialization code to the ArcSine component.
● Added initialization code to the ArcCosine component.
● Added initialization code to the ArcTangent component.
● Added initialization code to the Secant component.
● Added initialization code to the Cosecant component.
● Added initialization code to the Cotangent component.
● Added initialization code to the One over X component.
● Added initialization code to the Absolute component.
● Added initialization code to the Sign component.
● Added initialization code to the ToDegrees component.
● Added initialization code to the ToRadians component.
● Added initialization code to the N-Base log component.
● Added initialization code to the Smaller Than component.
● Added initialization code to the Larger Than component.
● Added initialization code to the Equal To component.
● Added initialization code to the Similar To component.
● Added initialization code to the Addition component.
● Added initialization code to the Subtraction component.
● Added initialization code to the Multiplication component.
● Added initialization code to the Division component.
● Added initialization code to the Integer Division component.
● Added initialization code to the Minimum component.
● Added initialization code to the Maximum component.
● Added initialization code to the Modulus component.
● Added initialization code to the Power component.
● Added initialization code to the Concatenate component.
● Added initialization code to the String Split component.
● Added initialization code to the String Join component.
● Added initialization code to the Evaluate Length component.
● Added initialization code to the Circle component.
● Added initialization code to the Circle CNR component.
● Added initialization code to the Arc component.
● Added initialization code to the Curve component.
● Added initialization code to the Interpolated Curve component.
● Added initialization code to the Offset Curve component.
● Added initialization code to the Offset Curve Loose component.
● Added initialization code to the Offset Curve On Surface component.
● Added initialization code to the Extend Curve component.
● Added initialization code to the Catenary component.
● Added initialization code to the Line SDL component.
● Added initialization code to the Fillet component.
● Added initialization code to the Fillet Distance component.
● Added initialization code to the Move component.
● Added initialization code to the Scale component.
● Added initialization code to the Mesh Plane component.
● Added initialization code to the Mesh Box component.
● Added initialization code to the Mesh Sphere component.
● Added initialization code to the Sphere component.
● Added initialization code to the Surface Offset component.
● Added initialization code to the Surface Offset Loose component.
● Added initialization code to the Divide Curve component.
● Added initialization code to the Divide Curve Length component.
● Added initialization code to the Divide Curve Distance component.
● Added initialization code to the Curve Frames component.
● Added initialization code to the Curve Perpendicular Frames component.
● Added initialization code to the Square Grid component.
● Added initialization code to the Rectangular Grid component.
● Added initialization code to the Vector Amplitude component.
--
David Rutten
david@mcneel.com
Poprad, Slovakia
…
e a fundamental failure on my part. On the other hand, Grasshopper isn't supposed to be on a par with most other 3D programs. It is emphatically not meant for manual/direct modelling. If you would normally tackle a problem by drawing geometry by hand, Grasshopper is not (and should never be advertised as) a good alternative.
I get that. That’s why that 3D shape I’m trying to apply the voronoi to was done in NX. I do wonder where the GUI metaphor GH uses comes from. It reminds me of LabVIEW.
"What in other programs is a dialog box, is 8 or 10 components strung together in grasshopper. The wisdom for this I often hear among the grasshopper community is that this allows for parametric design."
Grasshopper ships with about 1000 components (rounded to the nearest power of ten). I'm adding more all the time, either because new functionality has been exposed in the Rhino SDK or because a certain component makes a lot of sense to a lot of people. Adding pre-canned components that do the same as '8 or 10 components strung together' for the heck of it will balloon the total number of components everyone has to deal with. If you find yourself using the same 8 to 10 components together all the time, then please mention it on this forum. A lot of the currently existing components have been added because someone asked for it.
It’s not the primary components that catalyzed this thought but rather the secondary components. I was toying with a component today (twist from jackalope) that made use of three toggle components. The things they controlled are checkboxes in other apps.
Take a look at this jpg. Ignore differences; I did 'em quickly. GH required 19 components to do what SW did with 4 commands. Note the difference in screen real estate.
As an aside, I really hate SolidWorks (SW). But going forward, I’ll use it as an example because it’s what most people are familiar with.
"[...] has a far cleaner and more intuitive interface. So does SolidWorks, Inventor, CATIA, NX, and a bunch of others."
Again, GH was not designed to be an alternative to these sort of modellers. I don't like referring to GH as 'parameteric' as that term has been co-opted by relational modellers. I prefer to use 'algorithmic' instead. The idea behind parameteric seems to be that one models by hand, but every click exists within a context, and when the context changes the software figures out where to move the click to. The idea behind algorithmic is that you don't model by hand.
I agree, and disagree. I believe parametric applies equally to GH AND SW, NX, and so forth, while algorithmic is unique to GH (and GC and Dynamo I think). Thus I understand why you prefer the term. I too tend to not like referring to GH as a parametric modeler for the same reason.
But I think it oversimplifies it to say parametric modelers move the clicks. SW tracks clicks the same way GH does; GH holds that information in geometry components while SW holds it in a feature in the feature tree. In both GH and SW edits to the base geometry will drive a recalculation, but more commonly, it’s an edit to input data, beit equations or just plain numbers, that drive a recalculation.
I understand the difference in these programs. What brought me to GH is that it can create a visual dialog that standard modelers can’t. But as I've grown more comfortable with it I’ve come to realize that the GUI of GH and the GUI of other parametric modelers, while looking completely different, are surprisingly interchangeable. Do not misconstrue that I’m suggesting that GH should replace it’s GUI with SW’s. I’m not. I refrain from suggesting anything specific. I only suggest that you allow yourself to think radically.
This is not to say there is no value in the parametric approach. Obviously it is a winning strategy and many people love to use it. We have considered adding some features to GH that would make manual modelling less of a chore and we would still very much like to do so. However this is such a large chunk of work that we have to be very careful about investing the time. Before I start down this road I want to make sure that the choice I'm making is not 'lame-ass algorithmic modeller with some lame-ass parametrics tacked on' vs. 'kick-ass algorithmic modeller with no parametrics tacked on'.
Given a choice, I'd pick kick-ass algorithmic modeller with no parametrics tacked on.
2. Visual Programming.
I'm not exactly sure I understand your grievance here, but I suspect I agree. The visual part is front and centre at the moment and it should remain there. However we need to improve upon it and at the same time give programmers more tools to achieve what they want.
I'll admit, this is a bit tough to explain. As I've re-read my own comment, I think it was partly a precursor to the context sensitivity point and touched upon other stated points.
This now touches upon my own ignorance about GH’s target market. Are you moving toward a highly specialized tool for programmers and/or mathematicians, or is the intent to create a tool that most designers can master? If it’s the former, rock on. You’re doing great. If it’s the latter, I’m one of the more technically sophisticated designers I know and I’m lost most of the time when using GH.
GH allows the same freedom as a command line editor. You can do whatever you like, and it’ll work or not. And you won’t know why it works or doesn't until you start becoming a bit of an expert and can actually decipher the gibberish in a panel component. I often feel GH has the ease of use of DOS with a badass video card in front.
Please indulge my bit of storytelling. Early 3D modelers, CATIA, Unigraphics, and Pro-Engineer, were unbelievably difficult to use. Yet no one ever complained. The pain of entry was immense. But once you made it past the pain threshold, the salary you could command was very well worth it. And the fewer the people who knew how to use it, the more money you could demand. So in a sense, their lack of usability was a desirable feature among those who’d figured it out.
Then SolidWorks came along. It could only do a fraction of what the others did, but it was a fraction of the cost, it did most of what you needed, and anyone could figure it out. There was even a manual on how to use it. (Craziness!) Within a few short years, the big three all had to change their names (V5, NX, and Wildfire (now Creo)) and change the way they do things. All are now significantly easier to use.
I can tell that the amount of development time that’s gone into GH is immense and I believe the functionality is genius. I also believe it’s ease of use could be greatly improved.
Having re-read my original comments, I think it sounded a bit snotty. For that I apologize.
3. Context sensitivity.
"There is no reason a program in 2014 should allow me to make decisions that will not work. For example, if a component input is in all cases incompatible with another component's output, I shouldn't be able to connect them."
Unfortunately it's not as simple as that. Whether or not a conversion between two data types makes sense is often dependent on the actual values. If you plug a list of curves into a Line component, none of them may be convertible. Should I therefore not allow this connection to be made? What if there is a single curve that could be converted to a line? What if you want to make the connection now, but only later plan to add some convertible curves to the data? What you made the connection back when it was valid, but now it's no longer valid, wouldn't it be weird if there was a connection you couldn't make again?
I've started work on GH2 and one of the first things I'm writing now is the new data-conversion logic. The goal [...] is to not just try and convert type A into type B, but include information about what sort of conversion was needed (straightforward, exotic, far-fetched. etc.) and information regarding why that type was assigned.
You are right that under some conditions, we can be sure that a conversion will always fail. For example connecting a Boolean output with a Curve input. But even there my preferred solution is to tell people why that doesn't make sense rather than not allowing it in the first place.
You bring up both interesting points and limits to my understanding of coding. I’ve reached the point in my learning of GH where I’m just getting into figuring out the sets tab (and so far I’m not doing too well). I often find myself wondering “Is all of this manual conditioning of the data really necessary? Doesn’t most software perform this kind of stuff invisibly?” I’d love to be right and see it go away, but I could easily be wrong. I’ve been wrong before.
5. Components.
"Give components a little “+” or a drawer on the bottom or something that by clicking, opens the component into something akin to a dialog box. This should give access to all of the variables in the component. I shouldn't have to r-click on each thing on a component to do all of the settings."
I was thinking of just zooming in on a component would eventually provide easier ways to access settings and data.
I kinda like this. It’s a continuation of what you’re currently doing with things like the panel component.
"Could some of these items disappear if they are contextually inappropriate or gray out if they're unlikely?"
It's almost impossible for me to know whether these things are 'unlikely' in any given situation. There are probably some cases where a suggestion along the lines of "Hey, this component is about to run 40,524 times. It seems like it would make sense to Graft the 'P' input." would be useful.
6. Integration.
"Why isn't it just live geometry?"
This is an unfortunate side-effect of the way the Rhino SDK was designed. Pumping all my geometry through the Rhino document would severely impact performance and memory usage. It also complicates the matter to an almost impossible degree as any command and plugin running in Rhino now has access to 'my' geometry.
"Maybe add more Rhino functionality to GH. GH has no 3D offset."
That's the plan moving forward. A lot of algorithms in Rhino (Make2D, FilletEdge, Shelling, BlendSrf, the list goes on) are not available as part of the public SDK. The Rhino development team is going to try and rectify this for Rhino6 and beyond. As soon as these functions become available I'll start adding them to GH (provided they make sense of course).
On the whole I agree that integration needs a lot of work, and it's work that has to happen on both sides of the isle.
You work for McNeel yet you seem to speak of them as a separate entity. Is this to say that there are technical reasons GH can only access things through the Rhino SDK? I’d think you would have complete access to all Rhino API’s. I hope it’s not a fiefdom issue, but it happens.
7. Documentation.
Absolutely. Development for GH1 has slowed because I'm now working on GH2. We decided that GH1 is 'feature complete', basically to avoid feature creep. GH2 is a ground-up rewrite so it will take a long time until something is ready for testing. During this time, minor additions and of course bug fixes will be available for GH1, but on a much lower frequency.
Documentation is woefully inadequate at present. The primer is being updated (and the new version looks great), but for GH2 we're planning a completely new help system. People have been hired to provide the content. With a bit of luck and a lot of work this will be one of the main selling points of GH2.
It begs the question that I have to ask. When is GH1.0 scheduled to launch? And if you need another person to proofread the current draft of new primer.
patrick@girgen.com
I can’t believe wikipedia has an entry for feature creep. And I can’t believe you included it. It made me giggle. Thanks.
8. 2D-ness.
"I know you'll disagree completely, but I'm sticking to this. How else could an omission like offsetsurf happen?"
I don't fully disagree. A lot of geometry is either flat or happens inside surfaces. The reason there's no shelling (I'm assuming that's what you meant, there are two Offset Surface components in GH) is because (a) it's a very new feature in Rhino and doesn't work too well yet and (b) as a result of that isn't available to plugins.
I believe it’s been helpful for me to have figured this out. I recently completed a GH course at a local Community College and have done a bunch of online tutorials. The first real project I decided to tackle has turned out to be one of the more difficult things to try. It’s the source of the questions I posted. (Thanks for pointing out that they were posted in the wrong spot. I re-posted to the discussions board.)
I just can't seem to figure out how to turn the voronoi into legitimate geometry. I've seen this exact question posted a few times, but it’s never been successfully answered. What I'm showing here is far more angular than I’m hoping for. The mesh is too fine for weaverbird to have much of an effect. And I haven't cracked re-meshing. Btw, in product design, meshes are to be avoided like the plague. Embracing them remains difficult.
As for offsetsurf, in Rhino, if you do an offsetsurf to a solid body, it executes it on all sides creating another neatly trimmed body thats either larger or smaller than the original. This is how every other app I know of works. GH’s offsetsurf creates a bunch of unjoined faces spaced away from the original brep. A common technique for 3D voronois (Yes, I hit the voronoi overuse easter egg) is to find the center of each cell and scale them by this center. If you think about it, this creates a different distance from the face of the scaled cell to the face of the original cell for every face. As I've mentioned, this project is giving me serious headaches.
Don't get me wrong, I appreciate the feedback, I really do, but I want to be honest and open about my own plans and where they might conflict with your wishes. Grasshopper is being used far beyond the boundaries of what we expected and it's clear that there are major shortcomings that must be addressed before too long. We didn't get it right with the first version, I don't expect we'll get it completely right with the second version but if we can improve upon the -say- five biggest drawbacks (performance, documentation, organisation, plugin management and no mac version) I'll be a happy puppy.
--
David Rutten
Thank you for taking the time to reply David. Often we feel that posting such things is send it into the empty ether. I’m very glad that this was not the case.
And thank you for all of the work you've put into GH. If you found any of my input overly harsh or ill-mannered, I apologise. It was not my intent. I'm generally not the ranting sort. If I hadn't intended to provide possibly useful input, I wouldn't have written.
Cheers
Patrick Girgen
Ps. Any pointers on how to get a bit further on the above project would be greatly appreciated.
…
significant step towards Grasshopper 1.0
Since there is so much new stuff in 0.9 I feel I ought to caution you to not switch to the new version without carefully considering the pros and cons. There will most likely be serious bugs that our internal round of testing did not find, some of these bugs may prove so crippling to your work that you will not be able to use 0.9 until they are straightened out. You can of course always download the previous version, but you may not be able to open files made with 0.9 on earlier versions. So be careful to not overwrite old files unless you're certain that the new release is something you're happy with.
Grasshopper 0.9.0005 can be downloaded from the usual place. Note that you must have a recent version of the Microsoft C++ runtimes on your machine. See this FAQ post for more details.
Since 0.8 there have been three major changes, hopefully all for the better:
Clusters
AutoSave
DataMatching
Clusters have been rewritten. They are not done yet but done enough for initial testing. I wrote down some useful details about what's new, you can read them here.
AutoSave has been rewritten and works in a fundamentally different fashion. The goal was both to remove autosave files from visible locations and to provide a more robust recovery system in case things go awry. If you want to know more, some details are available here.
Data Matching has been tuned a bit. Some bugs have been solved and hopefully no new bugs have been introduced. Datatrees should now grow complex less rapidly in certain cases. Again, some nitty-gritty details can be found here. Due to the changes it is quite likely that a lot of old files that rely on a specific data-tree layout will no longer work. This is a necessary evil in my opinion, but be warned that this may cause significant delays while switching over to 0.9
Here follows a (not exhaustive) list of changes since 0.8.0066.
Important Changes:
Data Trees are now constructed differently in some cases, this may break files that depend on specific data tree layouts.
File format forwards compatibility has been broken. You may not be able to open files saved with 0.9.0005 on earlier versions.
Parts of the Grasshopper SDK have been broken. You may not be able to load GHA files compiled for earlier versions.
Component Data Matching menu items are no longer available, please use the dedicated matching components.
Components with one-shot option input parameters have almost all been replaced with components that have options in the menu.
AutoSaving behaviour has been redesigned to hopefully provide less fragile protection against data-loss.
We've had some serious crashes with the [Cloud Display] component. In some cases even Blue-screen crashes. Be sure all your work is saved (not just in Rhino) when you use [Cloud Display] component.
New features:
2600+ LolCats, but I stopped adding them as ICanHasCheezBurger is no longer fun.
Standard windows tooltips will be on screen for a longer period than the Windows default of five seconds.
Grasshopper will now load GHA files that are part of RHI installer packages.
Internal parameter data (aka 'persistent data') now supports data trees.
Set Multiple XXXX menu items that used a multi-line textbox now support data path lines.
Manage XXXX collection window now supports data path entries.
Moved a lot of components into the dropdown panels, reducing the default tab layout.
Ctrl+Alt and Shift+Ctrl+Alt Info modes now also highlight components on ribbon dropdowns.
It is now possible to create multiple new wires with a right-mouse-click during the new wire tool.
Added Preview Mesh quality settings to the Canvas Toolbar and Display menu.
Added AutoSave folder item to the File->Special Folders menu.
AutoSave settings now have buttons for deleting autosave files.
When a file is opened and a matching AutoSave file exists, options will be displayed.
Removed the Data Matching event checkbox from the AutoSave settings.
Added AutoSave folder options to the AutoSave settings.
Added Point Preview flavour menu item to the Display menu.
Shift+Click on a tab component icon now starts a component aggregate.
Clicking on the canvas instantiates the oldest component in an aggregate.
Shift+Clicking on the canvas instantiates all components in an aggregate.
Press Escape to destroy a component aggregate.
Alt+LeftClick on the canvas now starts the Split tool which pushes apart the objects on either side of the mouse.
MultiSave exit dialog now closes automatically when all documents have been saved.
Added Zooming widgets settings to the preferences Widget category for controlling ZUI display thresholds.
Added Context Menus settings to the preferences GUI category for enabled component cascading submenus.
Moved AutoSave and MRU preferences into a single category called Files.
Improved scrolling on the Preferences window.
Clusters can now be password protected.
Cluster data is now encrypted when a password has been set.
Clusters now have an option to include preview geometry of their content.
Clusters can now be edited properly.
Cluster hooks inherit data from the parent cluster during editing.
Copied clusters in the same file will update when one of them is changed (they are 'entangled').
Cluster tooltips now show information about entangled instances of a cluster in the document.
Cluster tooltips now show Author information.
Cluster tooltips now show whether a password has been set.
Cluster tooltips now have blurred content previews when a password has been set.
Clusters can now reference gh/ghx files.
Clusters can now reference ghcluster files.
Added *.ghcluster file type for cluster storage. *.ghcluster files retain author information and password protection.
Components with no runtime warnings or errors no longer have a "No message" entry in their menu.
Brep|Line intersection component no longer has a Limit First input param, this is now a component menu option.
Curve|Line intersection component no longer has a Limit First input param, this is now a component menu option.
Surface|Line intersection component no longer has a Limit First input param, this is now a component menu option.
Random component no longer has an Integers input param, this is now a component menu option.
Tree Branch component now has a 'Maintain Paths' component menu option.
BoundingBox component no longer has a Union input param, this is now a component menu option.
When connecting a Param Viewer to a new parameter, it will automatically resize if the size change isn't large.
Added Data Dam object to delay data across a network (Params.Special dropdown).
Added Interpolate Data component for sub-sampling collections of data (Math.Util dropdown).
Added Sift Pattern component for splitting data without messing with the item index (Sets.List panel).
Added Combine Data component for merging multiple streams with nulls (Sets.List panel).
Added Partition List component for breaking up lists into smaller lists (Sets.List dropdown).
Added Match String component for comparing strings against patterns (Sets.String dropdown).
Added String Distance component for computing Levenshtein distances between strings (Sets.Strings dropdown).
Added Format component for creating formatted strings (Sets.Strings dropdown).
Graft component has been replaced with a new one with additional component menu options (Sets.Tree panel).
Added To Polar component for transcribing XYZ points to plane Phi/Theta/R coordinates (Vector.Point dropdown).
Added Cloud Display component for displaying point data as fuzzy clouds (Vector.Point dropdown).
Added Sort Along Curve component for sorting points using curves as guides (Vector.Point dropdown).
Added Barycentric Point component for creating points using barycentric coordinates (Vector.Point dropdown).
Added Point Groups component for finding proximal clusters in point collections (Vector.Point dropdown).
Added Populate Geometry component for distributing points on different shapes (Vector.Grid dropdown).
All Population components now use a faster algorithm.
Added Project Point component (Vector.Point dropdown).
Added Blend Curve component for G0~G2 blends (Curve.Spline panel).
Added Connect Curves component for blending multiple curves into one (Curve.Spline dropdown).
Added Curve Length Domain component for measuring lengths of sub-domains (Curve.Analysis panel).
Added Curve Length Parameter component for measuring lengths to and from parameters (Curve.Analysis dropdown).
Added Segment Lengths component for finding shortest and longest segments in a curve (Curve.Analysis dropdown).
Added Containment Ex component for testing a point against multiple regions (Curve.Analysis dropdown).
Evaluate Curve component has been replaced with another one that outputs kink angles rather than lengths (Curve.Analysis panel).
Curve Derivatives component has been replaced with another one that has variable output parameters (Curve.Analysis dropdown).
Curve Derivatives component now displays the derivative vectors in the Rhino viewport.
Added Pull Curve component for pulling curves onto surfaces (Curve.Util dropdown).
Added Intersect Multiple Curves component (Intersect.Physical dropdown).
Added Matrix Data Type and Matrix Parameter (Params.Primitive dropdown).
Added Field Data Type and Field Parameter (Params.Geometry dropdown).
Replaced Boolean Toggle object with a new one (Params.Input panel).
Added a Button object for temporarily toggling a value (Params.Input dropdown).
Added Point Charge component (Vector.Field panel).
Added Line Charge component (Vector.Field panel).
Added Vector Force component (Vector.Field dropdown).
Added Spin Force component (Vector.Field dropdown).
Added Merge Fields component (Vector.Field panel).
Added Break Field component (Vector.Field panel).
Added Evaluate Field component (Vector.Field panel).
Added Field Line component (note: this one is unfinished) (Vector.Field panel).
Added Field Direction Display component (Vector.Field dropdown).
Added Field Perpendicular Display component (Vector.Field dropdown).
Added Field Scalar Display component (Vector.Field dropdown).
Added Field Tensor Display component (Vector.Field dropdown).
Added Adjust Plane component for modifying plane z-axes (Vector.Plane dropdown).
Added Cull Duplicate Points component (Vector.Point dropdown).
Added Evaluate component to replace all old expression components (Math.Script panel).
Added Expression component which evaluates an internal expression (Math.Script panel).
Added Short List component for equalizing list lengths (Sets.List panel).
Added Long List component for equalizing list lengths (Sets.List dropdown).
Added Cross Reference component for creating combinations of data (Sets.List panel).
Added Replace Nulls component for replacing null and invalid data (Sets.List dropdown).
Added Inside Multiple component for testing point inclusion with multiple breps (Surface.Analysis dropdown).
Added Collision component for testing one-to-many collisions (Intersect.Physical dropdown).
Added Collision component for testing many-to-many collisions (Intersect.Physical dropdown).
Added Mesh Inclusion component for testing point|mesh inclusion (Mesh.Analysis panel).
Added Mesh Closest Point component for finding the point on a mesh closest to another point (Mesh.Analysis panel).
Added Evaluate Mesh component for sampling position, normal and colour at a mesh parameter (Mesh.Analysis panel).
Added Face Boundaries component for converting mesh faces into polylines (Mesh.Analysis panel).
Added Mesh Edges component for extracting mesh edge lines (Mesh.Analysis panel).
Replaced Mesh Plane component with one that takes a rectangle (Mesh.Primitive panel).
Added Blur Mesh component for averaging mesh vertex colours (Math.Util dropdown).
Added Simple Mesh component for creating a minimal Brep representation (Mesh.Util dropdown).
Added Knot Style input for the Interpolate Curve component.
Added Knot Style input for the Interpolate Tangents Curve component.
Added four different display styles to the Legend object (accessible via the component menu).
Double clicking the Legend object toggles discrete vs. smooth display styles.
Added an extra input to the legend component which allows legend drawing in 3D.
Replaced Containment component with more sensible values for inside/coincident/outside.
Replaced the Recursive Voronoi component with a better one.
Convex Hull component will now solve for 2 points.
MultiDimensional Sliders can now be part of states.
Value Lists can now be part of states.
Control Knobs can now be part of states.
Geometry Pipeline object now has a Locked filter, available via the popup menu.
Geometry Pipeline object now has a Hidden filter, available via the popup menu.
Geometry Pipeline object now has a 'Group By Layer' option, available via the popup menu.
Geometry Pipeline object now has a 'Group By Type' option, available via the popup menu.
In Rhino5, the Zoom Extents command will now include Grasshopper preview geometry.
Expression input parameters can now have names like "Name (n)", where the text in brackets becomes the variable name.
Script input parameters can now have names like "Name (n)", where the text in brackets becomes the variable name.
Script output parameters can now have names like "Name (n)", where the text in brackets becomes the variable name.
VB/C# script components now have tooltip override fields in the context menu.
Parameter nicknames that collide with language keywords are now automatically modified in Script components.
Script Cache recovery for VB/C# components now displays the list of cached scripts much quicker.
VB/C# script editor now has a button for inserting skeleton Preview overrides.
Added Wrap option to Text Panel entries. When Wrap is off, items will be trimmed using ellipses.
Added NickName support to Knobs.
Added a grip region for Knob tuning.
Added a specific window for changing Knob settings.
Copy to Windows Clipboard now tries a total of 10 times if there's an access failure.
Copy to Windows Clipboard now copies to internal Grasshopper clipboard on prolonged failure.
Aborted solutions now clear whatever data is stored inside whatever component was solving when the Escape key went down.
The state of the Escape key is now also monitored during data conversions, making Escape behaviour more reliable.
Rearranged the Params.Special panel into Input and Util panels.
Rearranged the Sets.String panel.
File Reader component now reads per line files in a more efficient manner.
Parameter modifier icons are now drawn as vectors rather than bitmaps (good for hi-res export).
Component specific options and settings are now displayed as tags underneath components.
Markov Widget tooltip now shows component information rather than widget information.
Grips, Text and Capsule highlights on the canvas are now drawn using time-based rather than zoom-based transparency.
Parameter icons now fade in/out using time-based rather than zoom-based transparency.
Component icons now fade in/out using time-based rather than zoom-based transparency.
Histograms now fade in/out using time-based rather than zoom-based transparency.
Pie charts now fade in/out using time-based rather than zoom-based transparency.
Boolean Toggles now fade in/out using time-based rather than zoom-based transparency.
Timers now fade in/out using time-based rather than zoom-based transparency.
Data Dam objects now fade in/out using time-based rather than zoom-based transparency.
Cluster Input Hooks now fade in/out using time-based rather than zoom-based transparency.
Cluster Output Hooks now fade in/out using time-based rather than zoom-based transparency.
Colour Picker objects now fade in/out using time-based rather than zoom-based transparency.
Image Samplers now fade in/out using time-based rather than zoom-based transparency.
Legends now fade in/out using time-based rather than zoom-based transparency.
Data Recorders now fade in/out using time-based rather than zoom-based transparency.
Number Dials now fade in/out using time-based rather than zoom-based transparency.
Number Sliders now fade in/out using time-based rather than zoom-based transparency.
Bug fixes:
Components with Preview=Off would not display in selected only mode, this is fixed.
Instantiating number sliders via the popup box would not work if the first number was negative, this is fixed.
Copy to Windows Clipboard would not fail gracefully on error, this is fixed.
Interpolate Curve component would not warn on invalid degrees, this is fixed.
Knob menu control was not correctly initialized, this is fixed.
Knob menu control did not correctly respond to Limit On/Off, this is fixed.
Curve Discontinuity component would sometimes return invalid results for C1 discontinuities, this is fixed.
Certain exotic cases of Data Matching and Input Access would yield faulty output data trees, this is fixed.
Expressions in Point parameters would affect shared instances of points, this is fixed.
Editor window would not reflect saved/unsaved state of the loaded document, this is fixed.
MultiDimensional Slider would not undo on grip drags, this is fixed.
Image Sampler would not behave nicely when an image file went missing sometimes, this is fixed.
Upgrader for Null Item component generated an invalid result, this is fixed.
Text Panels would not display a scrollbar for local text, this is fixed.
Vector Display component would remain visible after disconnecting, this is fixed.
Vector Display Ex component would remain visible after disconnecting, this is fixed.
Adding or removing output parameters from VB/C# script would not update the script, this is fixed.
A CCX overlap intersection would sometimes result in erroneous parameters, this is fixed.
The tooltip over the abort icon would not show, this is fixed.
The canvas wouldn't always redraw when the solver was locked, this is fixed.
Transform Parameter Set menu items did nothing, they are now greyed out.
Occlusion Component would always return a null topology, this is fixed.
Group crossing selection would fail on concave group outlines, this is fixed.
Transform input parameters on components would have an empty transform by default, this is fixed.
Sweeps sometimes outputted surfaces with internal kinks, this is fixed.
Output parameters that output lists now have tooltip suffixes indicating them as such.
VB/C# script with no input parameter failed to run, this is fixed.
Tooltip title text for components and parameters was basically unreadable, this is fixed.
Transform component claimed "Mirrored Geometry" as an output, this is fixed.
Align Planes would output null values, this is fixed.
Flip curve component now has a different alignment algorithm for guide curves.
Panel Editor would fail to load when a certain Font was missing from the system, this is fixed.
Popup Component Insertion window would crash under certain conditions, this is fixed.
Timers that went through the clipboard would still target the original objects, this is fixed.
Group Tags would sometimes be clipped at Hi-Res export boundaries, this is fixed.
Obsolete components would be visible in the PopUp search if they were accessed via an alias, this is fixed.
Referenced geometry which no longer exists in Rhino is now stored as a null rather than invalid item.
There will probably be a flurry of releases following this one as bug-reports and wishes come in. If you feel skittish about diving into a dangerous beta feel free to wait until 0.9 has settled a bit.
Enjoy!
David
--
David Rutten
david@mcneel.com
Poprad, Slovakia…