From 92b292abd3b326037d345c79d047f9ce11a37e9b Mon Sep 17 00:00:00 2001 From: Chris Mackey Date: Wed, 17 May 2023 16:15:10 -0400 Subject: [PATCH] feat(extra): Add a component for screen-oriented text --- .../icon/LB Legend 2D Parameters.png | Bin 1325 -> 1323 bytes .../icon/LB Screen Oriented Text.png | Bin 0 -> 1347 bytes .../json/LB_Legend_2D_Parameters.json | 4 +- .../json/LB_Screen_Oriented_Text.json | 35 +++++++ .../src/LB Legend 2D Parameters.py | 9 +- .../src/LB Screen Oriented Text.py | 96 ++++++++++++++++++ .../LB Legend 2D Parameters.ghuser | Bin 5538 -> 5343 bytes .../LB Screen Oriented Text.ghuser | Bin 0 -> 5507 bytes 8 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 ladybug_grasshopper/icon/LB Screen Oriented Text.png create mode 100644 ladybug_grasshopper/json/LB_Screen_Oriented_Text.json create mode 100644 ladybug_grasshopper/src/LB Screen Oriented Text.py create mode 100644 ladybug_grasshopper/user_objects/LB Screen Oriented Text.ghuser diff --git a/ladybug_grasshopper/icon/LB Legend 2D Parameters.png b/ladybug_grasshopper/icon/LB Legend 2D Parameters.png index 3584e2540644cdbc5410b7be4f3819dc5606307d..0583defdd34f39964d9cc477a9a50f9109847a13 100644 GIT binary patch delta 1253 zcmVn}`Mi7Ns(sw}Cp1E->R<6y2PcWK*-Ci`*;)#6r1R4U+HN&D|q_Pv8#D&Cu2sVCIL-Ecj!bks7)!v8mFaci=Nh6 zwHjt`AUy`^Xn&KXjY)JmXx>S-%h^DioOLRmCsqinVHa>LyGW^2N(1RJFz|t4l`q5C z;ay|s7$ov-Fm`y>8WRPNWm!2Hkn9hR6>qw6D>m`K`YFIhK~sSY`VGM&TVvyB_VB;D z$pfnm*~m1ZH%*7#CK=Y57?>E9Qz8-_C3cdYW%Gos3V)=>z(_`XPU9jirkQvYpFNMp z_6~G)b)&kn3UgCtV`6ytS%bk4X*Qe1Duv=;j6zYSkjbwJYm6egOeuT)vN$B<5NVYZ z==c{Z-_@;KoRk3f!{1Q;!&R(YlIB~wWa+aD=gz_7@nFu(S%`{=dP^h{&CA-n1>Id; z=yJQ!(|^-Lj=SORbmL}KHI`c}kc9ZJ`fqG1Ej@$QIy)vzO@ZP>(=%#)ek!RSy?W&e ze!O-aec#Gu%b%vNSUG&Wqy$f%Jb`W7b|IT9G<}Y8 z@rSu-X%?hRp8@)W6P#lhi6bM?#EL7(x1rCg~nBqa}$b2(9f*c$`c%&At;C3WD+eg{|K@l7Z=y)-I3%=NIZ566p3gk~E8 zY0CWZjva6{HsKYqoArZ*K=39n&X^h{(~?djAiP@Uj6WYfdiOTHEmIcsG&3 z_@GNPE7LvA5a)UPOCPGMsvw^{`5v(~seh@dl0eeW%LYu}y>l0un_Q5H#KplHMMW0< zv^jj?c32j@hd;a?l%75VsYH53@N^8bj#ks9T8(y=KTJ`^=l4J){w!D<<-)DHdX%0z zCESCL0wqGEg84cxYYT>b&tS{jM$Ax%q){iwQPiGE5tDjZwYrhKG7bdew!GY}aDO)3 z7Me7NP*fq&k;xM$)*n551YWNfiN<&j@gn_c0gk5cV`KyZwGIa=%FE%f+fj4Vj%HUg zE`Rqud1A!-LqkK8S1ntP{{DV{_GWc8YV0-s&-8Tn;OE|6ESxuA7;Fi24ic-?-p$F% zMn3uWh5Pp7V9@~_C@jK3qM}a=kzTnm14^0fSXfvXw{XEbLwk08f&!b3R delta 1255 zcmV6_G z9``1F&uE&yXMAf!k85*84DYclD81pIs_1hs)){(nX6A5*YG^Kpn>M6QoGvZJlP6DL*}aF)<`Vsh zeD(XeNl7NeFIWirj2&9r1Y#y9Ly0x7Am4(X?tgB~5(q!@rl~k{ZZ7WJZsr?ZBvKG* ziOlQQrc6E^8^glbxKVO0CGw)XIg-ts>i}Ka2<^3Bp{;h0&n`HhEC~=f9u5uRbV(`S zY^yg-89&^+7mk)zyd)Hz^3|p&si~^QS6`O%`JLVpA-v*ebA$uX)r>+{HwHyX(|8!G z8-H~)H=(Pu3rczDs6-;s_~LO>1H?j6sjoIg+`hd9Xm4xBETQmIUyZzLt~^ZA-W+LQ zZ@6ueeV2#z1|#lww4t-J6Le_UkR&iLC!7xV{O|}b8elNz#Ff0KVVHDUNtdZr>cyTgMMeB^4+O$be6=Yq-EM3` z*|~H4J@~*|A_U8rFY>Z>Vq*LmEP1<$=?{T8Nt+)<6%w5Ynlq>Aq-K92~@|kh zCo3EIK7!(+qc~bvgkqwik6;Utxh(^7iR9GGnKQL-uY7Cl;Qo(LV6l)K$q*em zbQoLGHcx11x}CIJ;qCeyYK0<-EN{L@k&%%qvhuJ*%ZQ%$`G3E8ME@le^*c8sDy$19 Rt|b5f002ovPDHLkV1oQ3Zz%u( diff --git a/ladybug_grasshopper/icon/LB Screen Oriented Text.png b/ladybug_grasshopper/icon/LB Screen Oriented Text.png new file mode 100644 index 0000000000000000000000000000000000000000..1ff3af0d29fcf894a12699a14fbbb345fb63472b GIT binary patch literal 1347 zcmV-J1-$x+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1lUPLK~zXfy;XZm zm1P(|M5lv5+&Kq0-}%1xyBv^1Fp9-RMX(T=H=K>7f(SCZpv$%jxzted22;}3MpkZa zEkT@7spaLLT@;roJnxVsiJz+|ixok5p1gKJhz=L+DU30J;^ZU0!dR*z ziYr7>Of)1VJ*`eW4n-$xnHbz;5FAAcrz9LF9!oS`{V9ytqZ-#Y{~2o#K*>ZIx}ziAB;x zo*%?-5$U2J^x*1q$dB>Uiq*>wjHtW+PWzzNE5wSQ8hMS=C=_@EwALH_?NfJb5xZLC#cA|M~&+18RyTc)OB zAG&bpiUpb+TGJ~ij=p2$r#$pr5d z()o5tS~`AhNe>m|Rdhx1il@^&q|XK$ase_H=|{r#>?-?^^nBzbM2?FM^zk_y=hIl&ZeYr z66Y9=uX;2*JPeVJh&~+8JgO7@N`V(i8;6&>$Jf7gcSHW`Z%`~kQ)eQ~YPMW!YG{NTJw0F-r2*6=Ei`)p zqrs)T5%WGMDWO<`rcTGAh_Jas-Cf=4$_38WkD5aZX_&Qui_5-dY<2EXH|qT}1D-J+F9hNMED?8F;%>*h^h97p+T&j>GMtbRqk z+qVa9!?LtA$j-|8J12X?{dKRd87(O+f|rt#AED1X*lgaEnv(KxU|;~Mzd8zdYsRwH zt{Z&~U;pviTJ>S3FJD20>7{FMb8}1BkhLB_m2{?8M)_H+ms2Cl`!H zV^olTU~SFOYV>wM=da_wPBpK#<`^u9jk||aW@|I+uyb}Rv)Zc7{{F{_!T#psxY9|Y z##^m5_|M-gbDR63xM@Gn&a@+FPm0_Ok#002ovPDHLk FV1nO$jz|Ci literal 0 HcmV?d00001 diff --git a/ladybug_grasshopper/json/LB_Legend_2D_Parameters.json b/ladybug_grasshopper/json/LB_Legend_2D_Parameters.json index ae1cba4c..a11aa5d2 100644 --- a/ladybug_grasshopper/json/LB_Legend_2D_Parameters.json +++ b/ladybug_grasshopper/json/LB_Legend_2D_Parameters.json @@ -1,5 +1,5 @@ { - "version": "1.6.0", + "version": "1.6.1", "nickname": "Legend2D", "outputs": [ [ @@ -53,5 +53,5 @@ "code": "\n\ntry:\n from ladybug.legend import Legend2DParameters\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug:\\n\\t{}'.format(e))\n\n\ndef parse_dim_text(dim_text):\n \"\"\"Parse text representing a dimension into an input for legend parameters.\"\"\"\n try:\n px_txt = int(dim_text)\n return '{}px'.format(px_txt)\n except ValueError:\n return dim_text\n\n\n# parse all of the inputs\norigin_x_ = parse_dim_text(origin_x_) if origin_x_ is not None else None\norigin_y_ = parse_dim_text(origin_y_) if origin_y_ is not None else None\nseg_height_ = parse_dim_text(seg_height_) if seg_height_ is not None else None\nseg_width_ = parse_dim_text(seg_width_) if seg_width_ is not None else None\ntext_height_ = parse_dim_text(text_height_) if text_height_ is not None else None\n\n# make the 2D legend parameters\nleg_par2d = Legend2DParameters(origin_x_, origin_y_, seg_height_, seg_width_, text_height_)\n", "category": "Ladybug", "name": "LB Legend 2D Parameters", - "description": "Use this component to change the colors, numerical range, and/or number of divisions\nof any Ladybug legend along with the corresponding colored mesh that the legend refers to.\n-\nAny Ladybug component that outputs a colored mesh and a legend will have an input\nthat can accept Legend Parameters from this component.\n-" + "description": "Customize the properties of a screen-oreinted 2D legend displaying with the\n\"LB Preview VisualizationSet\" component.\n-" } \ No newline at end of file diff --git a/ladybug_grasshopper/json/LB_Screen_Oriented_Text.json b/ladybug_grasshopper/json/LB_Screen_Oriented_Text.json new file mode 100644 index 00000000..389a7395 --- /dev/null +++ b/ladybug_grasshopper/json/LB_Screen_Oriented_Text.json @@ -0,0 +1,35 @@ +{ + "version": "1.6.0", + "nickname": "Text2D", + "outputs": [ + [] + ], + "inputs": [ + { + "access": "list", + "name": "_text", + "description": "Text string to be displayed in the plane of the screen.", + "type": "string", + "default": null + }, + { + "access": "list", + "name": "leg_par2d_", + "description": "Optional 2D LegendParameters from the \"LB Legend Parameters 2D\"\ncomponent, which will be used to customize a text in the plane\nof the screen. Note that only the text_height, origin_x and origin_y\ninputs of this component affect the placement of the text.", + "type": "System.Object", + "default": null + }, + { + "access": "item", + "name": "_font_", + "description": "An optional text string to specify the font to be used for the text.\nExamples include \"Arial\", \"Times New Roman\", \"Courier\" (all without\nquotations). Default is \"Arial\".", + "type": "string", + "default": null + } + ], + "subcategory": "4 :: Extra", + "code": "", + "category": "Ladybug", + "name": "LB Screen Oriented Text", + "description": "Generate screen-oriented text that displays in the Rhino scene as a head-up\ndisplay (HUD).\n_\nThis is useful when there are certain summary results or information that should\nalways be displayed on-screen.\n-" +} \ No newline at end of file diff --git a/ladybug_grasshopper/src/LB Legend 2D Parameters.py b/ladybug_grasshopper/src/LB Legend 2D Parameters.py index d3d81577..a180ca64 100644 --- a/ladybug_grasshopper/src/LB Legend 2D Parameters.py +++ b/ladybug_grasshopper/src/LB Legend 2D Parameters.py @@ -8,11 +8,8 @@ # @license AGPL-3.0-or-later """ -Use this component to change the colors, numerical range, and/or number of divisions -of any Ladybug legend along with the corresponding colored mesh that the legend refers to. -- -Any Ladybug component that outputs a colored mesh and a legend will have an input -that can accept Legend Parameters from this component. +Customize the properties of a screen-oreinted 2D legend displaying with the +"LB Preview VisualizationSet" component. - Args: @@ -54,7 +51,7 @@ ghenv.Component.Name = 'LB Legend 2D Parameters' ghenv.Component.NickName = 'Legend2D' -ghenv.Component.Message = '1.6.0' +ghenv.Component.Message = '1.6.1' ghenv.Component.Category = 'Ladybug' ghenv.Component.SubCategory = '4 :: Extra' ghenv.Component.AdditionalHelpFromDocStrings = '0' diff --git a/ladybug_grasshopper/src/LB Screen Oriented Text.py b/ladybug_grasshopper/src/LB Screen Oriented Text.py new file mode 100644 index 00000000..46c5de5d --- /dev/null +++ b/ladybug_grasshopper/src/LB Screen Oriented Text.py @@ -0,0 +1,96 @@ +# Ladybug: A Plugin for Environmental Analysis (GPL) +# This file is part of Ladybug. +# +# Copyright (c) 2023, Ladybug Tools. +# You should have received a copy of the GNU Affero General Public License +# along with Ladybug; If not, see . +# +# @license AGPL-3.0-or-later + +""" +Generate screen-oriented text that displays in the Rhino scene as a head-up +display (HUD). +_ +This is useful when there are certain summary results or information that should +always be displayed on-screen. +- + + Args: + _text: Text string to be displayed in the plane of the screen. + leg_par2d_: Optional 2D LegendParameters from the "LB Legend Parameters 2D" + component, which will be used to customize a text in the plane + of the screen. Note that only the text_height, origin_x and origin_y + inputs of this component affect the placement of the text. + _font_: An optional text string to specify the font to be used for the text. + Examples include "Arial", "Times New Roman", "Courier" (all without + quotations). Default is "Arial". +""" + +from ghpythonlib.componentbase import executingcomponent as component +import Grasshopper, GhPython +import System +import Rhino +import rhinoscriptsyntax as rs + +class MyComponent(component): + + def __init__(self): + super(MyComponent,self).__init__() + self.text_2d_args = None + + def RunScript(self, _text, leg_par2d_, _font_): + ghenv.Component.Name = 'LB Screen Oriented Text' + ghenv.Component.NickName = 'Text2D' + ghenv.Component.Message = '1.6.0' + ghenv.Component.Category = 'Ladybug' + ghenv.Component.SubCategory = '4 :: Extra' + ghenv.Component.AdditionalHelpFromDocStrings = '0' + + try: + from ladybug.legend import Legend, Legend2DParameters + except ImportError as e: + raise ImportError('\nFailed to import ladybug:\n\t{}'.format(e)) + + try: + from ladybug_rhino.color import black + from ladybug_rhino.grasshopper import all_required_inputs, longest_list + except ImportError as e: + raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e)) + + import scriptcontext as sc + import Rhino.Geometry as rg + + if all_required_inputs(ghenv.Component): + # get the screen dimensions + active_view = sc.doc.Views.ActiveView.ActiveViewport + v_size = active_view.Size + vw = v_size.Width + vh = v_size.Height + _font = 'Arial' if _font_ is None else _font_ + + # convert the inputs into arguments to be rendered + self.text_2d_args = [] + for i, txt in enumerate(_text): + if len(leg_par2d_) == 0: # make default 2D parameters + l_par = Legend2DParameters() + else: + l_par = longest_list(leg_par2d_, i) + _height = Legend.parse_dim_2d(l_par.text_height, vh) + or_x = Legend.parse_dim_2d(l_par.origin_x, vw) + or_y = Legend.parse_dim_2d(l_par.origin_y, vh) + d_args = ( + txt, black(), rg.Point2d(or_x,or_y), False, _height, _font) + self.text_2d_args.append(d_args) + else: + self.text_2d_args = None + + def DrawViewportWires(self, args): + try: + if self.text_2d_args is not None: + # get the DisplayPipeline from the event arguments + display = args.Display + # render the 2D text from the arguments + for draw_args in self.text_2d_args: + display.Draw2dText(*draw_args) + except Exception, e: + System.Windows.Forms.MessageBox.Show(str(e), "script error") diff --git a/ladybug_grasshopper/user_objects/LB Legend 2D Parameters.ghuser b/ladybug_grasshopper/user_objects/LB Legend 2D Parameters.ghuser index 24200502f34f2172103a62be31d6bad8fe8724ad..2c3e75fb246ae7edda1ecc72020cd2d06f793ab4 100644 GIT binary patch literal 5343 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 diff --git a/ladybug_grasshopper/user_objects/LB Screen Oriented Text.ghuser b/ladybug_grasshopper/user_objects/LB Screen Oriented Text.ghuser new file mode 100644 index 0000000000000000000000000000000000000000..0bf1d4c173de19928fd7975f9132ce3aea1c7cb4 GIT binary patch literal 5507 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 F`wucG?{@$I literal 0 HcmV?d00001