he tools provided by System.Drawing (I know, there is a module called PIL that works in Python but I couldn't get it properly working so I just jumped to System namespace...).
The first problem that I found is that there is no a direct way to store colours into saved images in other format different than 8 bits per channel...
PixelFormat48bppRGB, PixelFormat64bppARGB, and PixelFormat64bppPARGB use 16 bits per color component (channel). GDI+ version 1.0 and 1.1 can read 16-bits-per-channel images, but such images are converted to an 8-bits-per-channel format for processing, displaying, and saving. Each 16-bit color channel can hold a value in the range 0 through 2^13.
From -> here.
...so the accuracy of the information stored is very very low (as much as 256 possible values per channel, ≈ 16M of different values per pixel) if I need to store the data in the hard-drive (thing that I would anxiously like to do for further processing).
So, is there any efficient way of storing at least 16bits (it's not an ideal solution but...it could work) per channel data into an image file using System namespace instead of an external library?.
...the thing is that I know that using:
imageTest = System.Drawing.Bitmap(mX,mY,System.Drawing.Imaging.PixelFormat.Format48bppRgb)
...I can create a 16bits per channel image, but how could I specify the 16bit color if System.Drawing.Color limit the range to 8bits values?
And ideally, does anyone knows how to work with and save directly floating point colours into image files using python?
Thanks in advance ;)
Ángel.
Sevilla, Spain.
…
Because the Adaptive methodology is founded upon the notion that there are hundreds of social factors that influence comfort and that the best we can do to forecast comfort is to find variables with good correlations to these social factors (like outdoor temperature), the premise that these published Adaptive model holds regardless of cultural norms is dangerous. Notably, the founders of the adaptive model have stressed that this particular linear correlation that you cite comes from recent surveys of buildings where people have both the the ability to open windows AND a great freedom to dress down. Hypothetically, if occupants were able to open the windows in Abraham's building but the cultural norm was that everyone was expected to wear multi-layered suits or dresses (as in historic Britain), a different correlation between outdoor temperature and comfort temperature would exist. In fact, historical European comfort surveys show that people likely preferred cooler temperatures in buildings (about 1-2C cooler) than today's occupants. Accordingly, after recognizing this social premise in the Adaptive model, I have built in a few ways to adjust/alter the version in Ladybug based on the literature I have read (even though these alterations are not a part of any official ASHRAE or European standard).
Abraham, you might have to be a bit more specific about how you would like to adjust the Adaptive comfort model for me to help your particular case and this may lead to me adding in new functionality. For the time being, I can tell you that the 'Ladybug_Adaptive Comfort Parameters' component is going to be your friend and I would recommend using the Adaptive Comfort Chart to visualize how you are changing the model. You can plug these 'Adaptive Comfort Parameters' into the 'Adaptive Comfort Recipe' component to have the microclimate analysis run with these parameters. Here are a few examples of how to alter the model:
1) Mixed-mode Building - Humphreys and the European Adaptive comfort team derived two separate correlations.
One for naturally ventilated buildings:
and conditioned buildings:
The dimensionless value between 0 and 1 for _levelOfConditioning allows you to create different correlations depending on whether occupants have complete freedom of dress and window operability (0) or have slight restrictions like in a mixed mode building (0.5, for example):
2) Changing Response Time of Occupants - There has been a bit of a debate in Literature about whether it is better to use the average monthly temperature or a weekly running mean temperature. The avgMonthORRunningMean input allows you to adjust this like so:
Average Month:
Running Mean:
3) Greater Temperature Range Tolerance - While this last one is actually a part of the European and Adaptive standards, you can adjust the range of the comfort band with either the 'eightyOrNintetyComf' input or the comfortClass input like so:
Ninety Percent Comfortable
Eighty Percent Comfortable
Abraham, let me know if you would like more controls over the model or if this is enough to do what you are thinking of. This example file allows you to construct the images I have above:
http://hydrashare.github.io/hydra/viewer?owner=chriswmackey&fork=hydra_2&id=Adaptive_Comfort_Chart&slide=0&scale=1&offset=0,0
-Chris…
l coarse mesh
Subdividing this mesh into strips of thin quads
Relaxing/Planarizing this mesh
Splitting and Unrolling
In this post I deal with the first 2 of these stages.
You can download the example definition here:
developable_strips_tutorial.gh
Drawing the initial mesh
To begin with we need a simple quad mesh. This can be modelled manually in Rhino, and only needs to use enough quads to give the topology and very rough form. No need to worry too much about the exact geometry or dimensions at this point, as we will refine and alter it as we go.
One very important thing that we do need to bear in mind though is that all internal vertices must have even valence (I covered this a bit in the earlier post here).
So for example, this is bad:
(because the highlighted vertex is surrounded by 5 faces)
While this is good (and can still be relaxed to the same shape):
(the top and bottom vertices have valence 8, and the vertices between the arms have valence 4)
With a little practice it should be possible to convert any mesh into one that meets this condition.
The reasons why we need this condition should become more clear in the later steps.
First subdivision
This is where we choose how many strips we want our final model to have, by applying a few rounds of subdivision using the Refine component (you could also use Weaverbird here):
Sorting the face directions
While quad meshes do not carry the same information about u/v directions as a NURBS surface, the individual faces do have a sort of direction given by their vertex ordering. However, these face directions are usually not consistently arranged, especially after subdivision.
The Kangaroo MeshDirection component attempts* to orient all the faces in a mesh so that they match with their neighbours.
For example, before sorting, if we draw a line from the midpoint of the first edge of each face to the midpt of its opposite edge, we might get something like this:
Whereas after sorting, we should get something like this:
*note that I say it attempts to orient the faces consistently. In some cases no valid solution exists, for instance if 3 or 5 faces meet around a vertex, hence the requirement mentioned at the start for even valence vertices.
Directional Subdivision
Now that we have consistent face directions across the mesh, we can apply further subdivision, but this time in one direction only. So we go from roughly square quads to thin rectangles. The idea is that as we apply higher levels of this directional subdivision, the final relaxed result goes towards something semi-discrete. A NURBS surface is fully continuous, and a mesh is fully discrete (made up of separate facets), while this strip model will be smooth in one direction and faceted in the other.
Go to part 2 for the next step of the process
…
eration!
See an example work flow for designing, simulating and analysing a Photovoltaic system below.
Download a Grasshopper and Rhino example file:
https://www.dropbox.com/s/krbszlplj5i40dz/017_HBgeneration%20Rhino%20model.3dm?dl=0
https://www.dropbox.com/s/lxneuzal3mipd2q/017_HBgeneration.gh?dl=0
See a quick introduction and tutorial videos here: https://www.youtube.com/playlist?list=PLrx2KnyhaJ5YXo5hpk8Q9q4Vy99O5IegK
1. Select a building to mount a photovoltaic generator on (seen in Rhino in green).
2. Select a surface within that building to mount a photovoltaic generator on (seen in Rhino in green).
3. Create a Honeybee context surface from that surface.
4. Place a photovoltaic generator on that Honeybee context surface by using the Honeybee generation component. Honeybee_Generator_PV and connecting the context surface to it's input _HBSurfaces. Then you can specify both the performance and the financial data of the photovoltaic generator.
5. Create a Honeybee generation system which consists of the photovoltaic generator in 4. By using the component Honeybee_generationsystem and connecting 4 to its input PVHBSurfaces_. Then you can specify the annual maintenance cost of this system.
6. Run the simulation in Energy Plus by connecting 5. to the input HBGenerators_.
7. Read the results of the simulation:
- The electricity produced by the Honeybee generation system in 5.
- The net purchased electricity of the facility (the Honeybee zone) to which the Honeybee generation system is attached to. This is the electricity consumed by the facility less the electricity generated by the Honeybee generation system.
- The financial costs of the Honeybee generation system; capital, maintenance and replacement costs.
8. Calculate the net present cost of the Honeybee generation system in 5 assuming a 25 year lifetime.
9. Visualise the net present cost.
…
complicated than it seems as I have an event and a subscriber method receiving data from a serial port.
In the code below, the strings received within myReceivedLines appear when connecting with the serial port (when connecttodevice is true). However they disapear when I launch another command (when homeallis true).
As you recommended in your reply, I have added the field called myReceivedLineswithin the class so that I could use the method String.Add() to all the feedback received and commands sent.
Why does the feedback dispear when a command is sent? Is the string going to myReceivedLine disappearing because they happen within a subscriber method or is it related to the DA.SetDataList() method used to assign myReceivedLinesto the output?
Many thanks!
public class SendToPrintComponent : GH_Component { //Fields List<string> myReceivedLines = new List<string>(); SerialPort port; //subscriber method for the port.DataReceived Event private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; while (sp.BytesToRead > 0) { try { myReceivedLines.Add(sp.ReadLine()); } catch (TimeoutException) { break; } } } protected override void SolveInstance(IGH_DataAccess DA) { //Opening the port if (port == null) { string selectedportname = default(string); DA.GetData(1, ref selectedportname); int selectedbaudrate = default(int); DA.GetData(2, ref selectedbaudrate); //Assigning an object to the field within the SolveInstance method() port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One); //Enables the data terminal ready (dtr) signal during serial communication (handshaking) port.DtrEnable = true; port.WriteTimeout = 500; port.ReadTimeout = 500; } //Event Handling Method bool connecttodevice = default(bool); DA.GetData(3, ref connecttodevice); if (connecttodevice == true) { if (!port.IsOpen) { port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); DA.SetDataList(0, myReceivedLines); port.Open(); } } else if (port.IsOpen) { port.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler); port.Close(); } if (port.IsOpen) { DA.SetData(1, "Port Open"); } //If the port is open do all the rest if (port.IsOpen) { bool homeall = default(bool); DA.GetData(5, ref homeall); //Home all sends all the axis to the origin if (homeall == true) { port.Write("G28" + "\n"); myReceivedLines.Add("G28" + "\n"); DA.SetDataList(2, myReceivedLines); } } else { DA.SetData(1, "Port Closed"); } }}…
IME. DO NOT COMPOUND HAVING A LATE PROJECT WITH ALSO MISSING CLASS.
Readings/Discussion:
Digital Pin-Up
Class Dropbox Resources:
https://www.dropbox.com/sh/mv8ugl1pqu3x8vf/AADa0gbxpyKI_6VI8uYtZdap...
Exercise:
Kangaroo
Galapagos
Links:
The Bad Cafe
http://www.archdaily.com/796873/the-bad-cafe-nudes
50 Digital Joints
http://www.archdaily.com/797107/50-downloadable-digital-joints-for-woodworking
Fun DC Stuff This Week
http://dcist.com/2016/10/16_of_our_favorite_events_in_dc_thi.php
Lean Urbanism
http://leanurbanism.org/
Augmented Reality
http://www.archdaily.com/796616/limelight-projects-psychedelic-augmented-reality-lightshow-onto-the-romanian-parliament-building
Photovoltaic Facade
http://www.archdaily.com/796704/60-storey-tower-maximizes-energy-capture-with-photovoltaic-facade
New Office Pods
http://www.archdaily.com/796317/mit-and-google-team-up-to-create-transformable-office-pods…
) membrFP.Faces[0], // start/quide surface: going from DC to NY via LA uSpans, // obvious vSpans, // obvious true, // trim outer loop. Fails in most of cases. NOTE: inner loops ARE NOT treated false, // tangency 1.0, // point spacing patchFlexibility, // flexibility: use a generous value around 50 surfPullFactor, // surface pull factor (this needs some investigation) fixedges, // get 4 false values you stupid method, like that? 0.2); // tolerance - be generous: we are talking about tissues here not NASA sourced things
Do you know of a generic container in Rhincommon I can store geometry form meshes, breps and curves to points? That's what I seem to need to get around the IEnumerable error.
I have to figure out how to format the Boolean array in Python. Ah, parenthesis worked!
P = Rhino.Geometry.Brep.CreatePatch(CURVES_CONTAINER, Starting_Surface[0], 10, 10, True, False, 10, 30, 0, (False, False, False, False), 1)
At long last, only to find out it won't work right, as in no setting of flexibility will affect it at all?!
Tolerance has a sudden crazy effect if I turn it way up, like a piece of paper bending up opposite corners and it no long is trimmed, but flexibility is dead. I used your same values and same curves for everything. Yes, all the curves are participating, if I bake them and move them around.
My Patch is broken. Weird. Is there magic with the starting surface? I made a naive assumption just a plane would do. Yet you seem to be using your simple CreatePatch results for this?
Ah, the second CreatePatch command type that takes only a surface gives the same thing, nearly. You need a starting surface at all?! They said you could now leave that out as of Rhino SR10 by using Null, but Null or Nothing gives an error. How do I make a null? In Python it's None, as in just entering None into the Rhinocommon command or assigning a variable to None.
Now I have a patch!
But your's is more expressive, more crazy, like your starting surface is greatly influencing it to have extremely extended feet, whereas mine works like a normal patch, as if you were trying to smooth over things. And indeed your surface pull slider makes it more obvious you chose a specific starting surface attached to one of the curves. My starting planes had no such effect, earlier.
With such a starting surface to bias the results I get the same thing finally, indeed, good to know what that does, I never knew from using the command in Rhino.
Why did my use of a plane shut this down so badly though?! Crazy command.
I've enclose a working script for the record.…
Added by Nik Willmore at 12:47am on February 26, 2016
using Grasshopper.Kernel.Data; using Grasshopper.Kernel.Types;
using System; using System.IO; using System.Xml; using System.Xml.Linq; using System.Linq; using System.Data; using System.Drawing; using System.Reflection; using System.Collections; using System.Windows.Forms; using System.Collections.Generic; using System.Runtime.InteropServices;
/// <summary> /// This class will be instantiated on demand by the Script component. /// </summary> public class Script_Instance : GH_ScriptInstance { #region Utility functions /// <summary>Print a String to the [Out] Parameter of the Script component.</summary> /// <param name="text">String to print.</param> private void Print(string text) { /* Implementation hidden. */ } /// <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary> /// <param name="format">String format.</param> /// <param name="args">Formatting parameters.</param> private void Print(string format, params object[] args) { /* Implementation hidden. */ } /// <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary> /// <param name="obj">Object instance to parse.</param> private void Reflect(object obj) { /* Implementation hidden. */ } /// <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary> /// <param name="obj">Object instance to parse.</param> private void Reflect(object obj, string method_name) { /* Implementation hidden. */ } #endregion
#region Members /// <summary>Gets the current Rhino document.</summary> private readonly RhinoDoc RhinoDocument; /// <summary>Gets the Grasshopper document that owns this script.</summary> private readonly GH_Document GrasshopperDocument; /// <summary>Gets the Grasshopper script component that owns this script.</summary> private readonly IGH_Component Component; /// <summary> /// Gets the current iteration count. The first call to RunScript() is associated with Iteration==0. /// Any subsequent call within the same solution will increment the Iteration count. /// </summary> private readonly int Iteration; #endregion
/// <summary> /// This procedure contains the user code. Input parameters are provided as regular arguments, /// Output parameters as ref arguments. You don't have to assign output parameters, /// they will have a default value. /// </summary> private void RunScript(bool bake, List<GeometryBase> G, Point3d L, Color C) { COL = C; LOCATION = L; NAME = ""; pnts.Clear(); crvs.Clear(); breps.Clear();
foreach(GeometryBase geom in G){ switch(geom.GetType().Name){ case "Point": pnts.Add(((Rhino.Geometry.Point) geom).Location); break; case "Curve": //create a new geometry list for display break; case "PolyCurve": crvs.Add((PolyCurve) geom); break; case "Brep": breps.Add((Brep) geom); break; default: Print("Add a new case for this type: " + geom.GetType().Name); break; } }
if(bake){ Rhino.DocObjects.InstanceDefinition I = doc.InstanceDefinitions.Find(NAME, false);
if(I != null) doc.InstanceDefinitions.Delete(I.Index, true, true);
int index = doc.InstanceDefinitions.Add(NAME, "description", Point3d.Origin, G); doc.Objects.AddInstanceObject(index, Transform.Scale(L, 1)); } }
// <Custom additional code> //GEOMETRY Lists to display
List<Point3d> pnts = new List<Point3d>(); List<PolyCurve> crvs = new List<PolyCurve>(); List<Brep> breps = new List<Brep>();
string NAME; Point3d LOCATION; int THICKNESS = 2; Color COL;
//Return a BoundingBox that contains all the geometry you are about to draw. public override BoundingBox ClippingBox { get { return BoundingBox.Empty; } } //Draw all meshes in this method. public override void DrawViewportMeshes(IGH_PreviewArgs args) {
}
//Draw all wires and points in this method. public override void DrawViewportWires(IGH_PreviewArgs args) { foreach(Point3d p in pnts) args.Display.DrawPoint(p, Rhino.Display.PointStyle.ControlPoint, THICKNESS, COL);
foreach(PolyCurve c in crvs) args.Display.DrawCurve(c, COL, THICKNESS);
foreach(Brep b in breps) args.Display.DrawBrepShaded(b, new Rhino.Display.DisplayMaterial(COL));
args.Display.DrawPoint(LOCATION, Rhino.Display.PointStyle.ActivePoint, 3, Color.Black); args.Display.Draw3dText(NAME, Color.Gray, new Plane(LOCATION, Vector3d.ZAxis), THICKNESS / 3, "Arial"); }
// </Custom additional code> }…
main attention is set on easy to handle interface , which should be used at a early stage of conceptual design to respond to external and internal influences in a intelligent and sustainable way.
Participants will use the software Grasshopper as a parametric modeling plug-in for Rhino. The usage of this graphical algorithm editor tightly integrated with Rhino’s 3-D modeling tools open up the possibility to construct highly parametrical complex models. To generate this complexity we will use live linkages to several programs listed below:
• Autodesk Ecotect Analysis and Radiance via GECO
• Processing, Excel or Open Office via gHowl
• FEA software GSA via SSI
In this 3 intense days, the participants should learn the workflow of the plug-ins with the help of examples and get an overview of the different software’s, there possibilities for evaluating the performance of a design or the usage of additional tools to be not chained to a single system .
(e.g. parametrical accentuation, parametrical formation, parametrical reaction)
TIME AND LOCATION
27th – 29th September 2010Leopold-Franzens university innsbruck/austria
Technik Campus | ICT - building
Technikerstraße 21a
A - 6020 Innsbruck | Austria
47°15’50.71”N 11°20’43.45”E
detailed program as pdf-version
FOR WHOM
All levels are welcome (students & professionals)
The only requirement is knowledge of Rhino and Basic Grasshopper.
You will need a level which corresponds to the Grasshopper Primer course outline.
FEES
21 hours
professionals: 395€
students (bachelor/master): 250€.
REGISTRATION
please send a email to to.from.uto@gmail.com attached with following information :
Last Name
First Name
Date of Birth
Nationality
Email Address
Current Address
Profession or proof of student status
After submitting you will receive an email with a PayPal link to complete registration.…