Ruby & Text Macro Basics.


Joe_Carrick
 Share

Recommended Posts

Ruby Console

Chief provides a Ruby Console which allows you to inspect what attributes are available for an object and also check the values of those attributes. There is a basic tutorial on using the Ruby Console which should be reviewed. You can do this by opening the Ruby Console and typing tutorial.

Here are some basics:

When you have an object selected in Chief and then in the Ruby Console type owner.names.sort you will see a list of all the attributes available for that object. Let's say that you have a room selected:

Some of the attributes will be name, standard_area, internal_area, type_name
You can then type owner.standard_area and Ruby will display that data. Note that Ruby is case sensitive.

Ruby recognizes data as String, Integer, Floating Point, Logical, Array or Hash.
Here are some basic methods that can be used to modify the data:
.to_i converts string or floating point value to an integer
.to_f converts string or integer value to a floating point
.to_s converts an integer or floating point value to a string
.round(n) rounds a floating point value to n places
.gsub(str1,str2) substitutes str2 for str1 in a string

To use a method you simply add the method after the data. For example if the room is 247.68342 sq.ft.
owner.standard_area.round(0).to_s will return a string with no decimal places displayed. ie: 248
owner.standard_area.round(0).to_s + "Sq.Ft." will return 248 Sq.Ft.

So far it's just the Ruby Console. Anything you do there is not going to effect anything displayed in your Plan - but it is a good place to experiment with the modifiers and any calculations that you want to impose to get a result.

Text Macro Management - New

To create a macro so we can access and display data requires that the macro knows it's "Context". There are 3 possibilities:

None ........... The data is independent of any Chief Object (It's just text or numerical data typed in the macro).
Owner ......... The attribute is from a Chief Object via it's Label (the macro has to b included in the Default Label
Referenced . The attribute is from a Chief Object (usually CAD) that is connect to a Text Box by an Arrow.

So, using the example above we can add to the Room Label by having an "Owner Context" macro named Room Standard Area which consists of "Standard Area = " + owner.standard_area.round(0).to_s + "Sq.Ft.".

In the Default Room Label we would then add %Room Standard Area% and Standard Area = 248 Sq.Ft. would be added to the Room Label. Actually the number would be different for each room but the data would be displayed in all Room Labels.

For objects like Closed Polylines we have to use a Text Box with an arrowhead connected to the Polyline. In that case our macro would be:

"Area = " + referenced.area.round(0).to_s + "Sq.Ft."

By using a Text Box, we can get a note with multiple lines and if it's a Rich Text Box we can get additional formatting.

The return value of any macro is the last line of the macro. So if you want to use a macro to perform a calculation and store it in a global variable ($MyVariable) but display nothing you just add 2 single quote marks as the last line. This can be very handy for use in Default Labels, allowing a calculation to be made and the data store where we can use it later without changing the displayed Labels.

There are a lot of additional things that can be done, but I hope the above provides a little better understanding.

  • Upvote 4
Link to comment
Share on other sites

Avoiding Evaluation Errors

 

Sometimes we need to check the output of a macro while in edit mode but the object selected is one that doesn't have a Label so our context will need to be "Referenced".  However, if we have selected a "Close Polyline" then while we are in the Text Macro Management dialog the context will in fact be "Owner".  In order to make our macro work without an error we need to use a "Block of Code" to handle the error smoothly.  Here's an example:

 

begin

  result = owner.area

rescue

  result = referenced.area

end

result = "Area = " + result.round(0).to_s + " Sq.Ft."

return result

 

This code will work with either context.

Link to comment
Share on other sites

Nope, nope, nope

You can not use the ending return statement within a macro -- only within a method.

Just use

result = "Area = " + result.round(0).to_s + " Sq.Ft." without the next line Or just "......" or "Area = #{result.round(0)} Sq. Ft."

this is b/c Chief wraps the macro within a "eval" statement before they deliver it to the script engine, -- & you can not use return there. You can only use "return" within a method. It is also the reason you can not use a "put" or "p" within a Macro but you can in the Console. Just another anomaly not explained by Chief which make this so cumbersome to use and understand.

Link to comment
Share on other sites

Thanks Gerry,

 

My mistake adding the last line.  I should have left that off.

 

begin

  result = owner.area

rescue

  result = referenced.area

end

"Area = " + result.round(0).to_s + " Sq.Ft."

 

would be correct as would your syntax of:

 

"Area = #{result.round(0)}  Sq. Ft."

 

It's easier for me to read the way I show it but both give the same output.

IAE, the point of this was to indicate how to have a macro work with either context.  Something you pointed out in another thread.

Link to comment
Share on other sites

My method is a little different than Gerry's (I allow the specification of the fractional denominator and I format the output differently when the value is less than a foot) but essentially the answer to your question is yes - but only by adding a macro to the Default Room Label.  Using Gerry's basic code the macro would need to be:

 

arr = (ceiling_elevation-floor_elevation).divmod(12)

inch_frac = ((arr[1]-arr[1].floor)*16).round.quo(16)

 

result = case inch_frac

  when Rational(1.0)

    "#{arr[0]}'-#{arr[1].ceil}\""

  when Rational(0.0)

    "#{arr[0]}'-#{arr[1].floor}\""

  else

    "#{arr[0].floor}'-#{arr[1].floor} #{inch_frac}\""

  end

result + "CLG"

 

I modified Gerry's code mainly by using (ceiling_elevation-floor_elevation) so that it would give the right value.

The basic problem with this is that it will just be added to the Room Label on the same line and at the same text size as the Room Name.

Link to comment
Share on other sites

Ok I am lost I copied what I believe to be the marco for the room clg or wall plate height, I open up text macro management made a new one named it my room clg height and then pasted the copied macro into the value area when I went to use it the macro was greyed out what did I do wrong

  • Upvote 1
Link to comment
Share on other sites

Two questions:

 

I added the two ceiling macros in Text Macro Management, but when I go to Defaults - Room  - Room Label to add it to the label all of the user defined macros are greyed out. Why?

 

When using a the (Plan) Ceiling Height macro in Defaults - Room  - Room Label it does not recognize a Ceiling Plane that has been placed in the plan, but instead takes the measurement from the underside of the floor joist above the ceiling plane. Is there a way to get the ceiling macro to recognize the ceiling plane?

 

Thanks

 

post-571-0-46332500-1429059449_thumb.jpg

Link to comment
Share on other sites

Two questions:

 

I added the two ceiling macros in Text Macro Management, but when I go to Defaults - Room  - Room Label to add it to the label all of the user defined macros are greyed out. Why?

 

Macros are only valid if a object is selected as in a label. The room default DBX deselects all rooms when you open it So you have to type  in the macro from memory.

 

When using a the (Plan) Ceiling Height macro in Defaults - Room  - Room Label it does not recognize a Ceiling Plane that has been placed in the plan, but instead takes the measurement from the underside of the floor joist above the ceiling plane. Is there a way to get the ceiling macro to recognize the ceiling plane?

 

No -- But if you're just lowering the finish, you can use "finish_ceiling_elevation" instead.

 

Thanks

Link to comment
Share on other sites

Thanks, Gerry. Part one I figured out after I posted, unfortunately.

 

As for my second question, even using the Finish Ceiling Macro, it returns a value taken from the floor joist above the ceiling plane (less the value for the ceiling finish). In the attached cross section you can see that the finish ceiling height is 107" but the Label in plan is showing 113".

post-571-0-29917900-1429062895_thumb.jpg

post-571-0-55035600-1429062909_thumb.jpg

Link to comment
Share on other sites

 

No -- But if you're just lowering the finish, you can use "finish_ceiling_elevation" instead.

 

No! No! No!

 

That is an absolute elevation measured from 0.00 (aka Level 1 floor).  So using that attribute will only work on the 1st floor.  On any other floor it will not give you the ceiling height.

 

Chief has the information and it can be used to advantage only if you use it correctly.  You must use (finish_ceiling elevation - finish_floor_elevation) to get the finish ceiling height.

 

 

Link to comment
Share on other sites

Joe and Gerry,

 

I am not versed in writing script so unfortunately I would not know what to do with the information both of you have provided. I assume, however, that with this change (to the macros you have provided?), you believe it will calculate the finish ceiling height to the Ceiling Plane which has been place under the floor structure (as in the pic I provided) even thought the Chief Macro "Room Ceiling Height Finish"  (which can be found in Defaults - Rooms - Room Label - Insert - Global - Room Info - Room Ceiling Height Finish) does not. (But, shouldn't it???)

 

If either or both of you want to post your modified macro, or show me where/how to insert that information, I would appreciate it.

 

Also, shouldn't Chief allow a room to stay selected so as to be able to access the User Defined Macros in Room Label Defaults, or is just me?

 

Thanks

Link to comment
Share on other sites

Ok -- I'll try one more time -- But the bar keeps moving

I see that you are using a manual ceiling plane in your post. Chief has no elevation info (annotation) avail for manually inserted ceiling planes, either via Ruby macros or its Global macros. The height info avail is only for the room itself. As I mentioned, if you want to auto annotate a lowered room height, you can only lower the ceiling by lowering the ceiling finish then use the ruby attribute - finish_ceiling_elevation or the Global %room.height.ceilingfinish% Even if you put the global in the ceiling plane label, it's still going to only measure to the room ceiling finish and not the inserted plane height.

Joe was referring to the fact that the macro return values are absolute. So if you have a second floor you also have to sub out the floor elevation. It does not matter on the first floor since the floor elev on that floor is 0 - normally.

As to your second question it probably should but probably that was just a programming shortcut taken.

Link to comment
Share on other sites

Make sure you review the Ruby tutorial and experiment with it to see what is available.

It would also be a good idea to go back to the 1st post in this thread and read carefully what it says about "Context".

 

Labels are "Owned" by their object - so in the case of a macro used in a Label (room. door, cabinet, window, wall, etc) the context must be "Owner".  Labels are the only thing that I know of at this time that uses the "Owner" context.

 

Text Blocks that connect to Polylines or other CAD objects via an arrow require a "Referenced" context.

 

Macros that do not rely on any Chief Object to retrieve data - such as general notes, etc. do not need to be any context other than "None".  The Text in these macros can be typed and/or the values contained in "Ruby Global Variables". 

Link to comment
Share on other sites

Joe was referring to the fact that the macro return values are absolute. So if you have a second floor you also have to sub out the floor elevation. It does not matter on the first floor since the floor elev on that floor is 0 - normally.

 

Even that's not really correct since the finish_floor_elevation is likely not 0.00 even on the 1st floor.  If you really want the finished ceiling height you need to used both attributes.  There really is no reason to take a short cut - the macro if written correctly will work for all floors.

Link to comment
Share on other sites

  • 3 years later...

I wonder if it's possible for Chief to give us a visual scripter, for those of us that are not programmers? I think the visual scripter in Vectorworks, Marionette, is like that?

 

I posted a request in Suggestions...

 

 

 

Link to comment
Share on other sites

Ruby could not be adapted to create a visual scripter, However, several scripting languages are used within a scripter to enhance their capabilities as with Python used in Grasshopper.

 

However, I think you find the Scripters are more complicated than any language such as Ruby or Python. Don't think a scripter would accomplish too much and would be too complicated for the average designer in Chief. 

 

Would like to see Ruby enhanced to the point that it is practical for the average user to use and understand - Would accomplish more?

  • Upvote 3
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share