Running a .rb file in Chief


tlinder
 Share

Go to solution Solved by Alaskan_Son,

Recommended Posts

I'm trying to run a .rb file that's on my local in CA by using a marco. Right now I can only get it to read the file. Does anyone have any insight on how I might be able to to this or where I need to look?

 

Macro: In CA

File.read("C:/Users - Desktop/scope1.rb")

 

 

Output: from text stored on a local drive

rafter_length = (length.to_f.round / 12) + 1

convert_to_int =  rafter_length.even?

case
  when convert_to_int == true
  resut = rafter_length

  when convert_to_int == false
  result = rafter_length +1
end

 

image.thumb.png.cead1fc53c54f9b5db1e2d8aa77354ed.png

 

Link to comment
Share on other sites

You should just make this an evaluated macro in chief, context: owner

 

 

rafter_length = (length.to_f.round / 12) + 1

convert_to_int =  rafter_length.even?

case
  when convert_to_int == true
  result = rafter_length

  when convert_to_int == false
  result = rafter_length +1
end

 

Using an rb in this case is superfluous.  IAE, to use one you would need to "require" it in your chief macro and then call any specific "defined" function within that rb file.  The only reason for using an rb file is for utility functions that aren't otherwise available that you would need in many different user macros.  This one is object specific to any object that has a "length" attribute.

Link to comment
Share on other sites

3 minutes ago, Joe_Carrick said:

You should just make this an evaluated macro in chief, context: owner

 

 

rafter_length = (length.to_f.round / 12) + 1

convert_to_int =  rafter_length.even?

case
  when convert_to_int == true
  result = rafter_length

  when convert_to_int == false
  result = rafter_length +1
end

 

Using an rb in this case is superfluous.  IAE, to use one you would need to "require" it in your chief macro and then call the "defined" function within that rb file.

Thanks Joe

The macro works in evaluated, just trying to take it one step further and save the company a lot of time.

I'm am trying to read it from my local so I don't have to open every CA file and update them 1 by 1. We have hundreds of files.

Link to comment
Share on other sites

9 minutes ago, tlinder said:

Thanks Joe

The macro works in evaluated, just trying to take it one step further and save the company a lot of time.

I'm am trying to read it from my local so I don't have to open every CA file and update them 1 by 1. We have hundreds of files.

You don't read the rb file.  You "require" it.  Within that file you need to define the function"int_length"and then in your macro you call the function.

ie:  

  • result = int_length(length)

 

Link to comment
Share on other sites

Here's a sample rb file that has a series of defined methods.  Note that I no longer use this since it's problematical to update with each new version of chief.

 

#=================================================
# Joe's Macro Subscription Service
#   Ruby script: Float Class     
#   Copyright October 1, 2015 by Joseph P. Carrick
#=================================================
# The contents of this Ruby Macro is not to be
# revealed to any other Chief Architect user or 
# employee.  If a violation of this requirement
# is found, the offending subscriber's
# subscription will be immediately terminated.
#=================================================
# Place this file in Chief Architect/Data/Scripts
# folder.  Then place the following:
#    require "Float Class.rb"
# at the beginning of any macro where you want to
# use these methods
#=================================================
 
class Float
    #=================================================================
    # Display a numerical value formatted according the the current
    # units of the Plan.  Requires $Units to be either "Imperial" or
    # "Metric" to recognize the units.
    #=================================================================
    def format_number(n)
        if $Units.nil?
            result = self.sig(3)
        elsif $Units == "Imperial"
            result = self.ftin(32)
        elsif $Units == "Metric"
            result = self.meters(n)
        else
            nvalue = self.sig(3)
        end
        return result
    end

    #=================================================================
    # Display a value (decimal inches) formatted as a text string
    #    syntax:  nvalue.ftin(denominator)
    #    example: n = 64.125
    #             s = n.ftin(8)  ->  5'-4 1/8"
    #=================================================================
    def ftin(denominator)
        if $Units.nil?
            nvalue = self
        elsif $Units == "Imperial"
            nvalue = self
        elsif $Units == "Metric"
            nvalue = self/2.54
        else
            nvalue = self
        end
        arr = self.divmod(12)
    if arr[1] >= 11.96875
      arr[0] = arr[0]+1
      arr[1] = 0.00
    end
    
        inch_frac = ((arr[1]-arr[1].floor)*denominator).round.quo(denominator)
    
        if arr[0].floor < 1
            if inch_frac == 1.0
                result = "#{arr[1].ceil}"+'"'
            elsif inch_frac == 0.0
                result = "#{arr[1].floor}"+'"'
            elsif inch_frac < 1 and arr[1].floor > 0
                result = "#{arr[1].floor} #{inch_frac}"+'"'
            elsif inch_frac < 1
                result = "#{inch_frac}"+'"'
            else
                result = "#{arr[1].floor} #{inch_frac}"+'"'
            end
        else
            if inch_frac == 1.0
                result = "#{arr[0]}'-#{arr[1].ceil}"+'"'
            elsif inch_frac == 0.0
                result = "#{arr[0]}'-#{arr[1].floor}"+'"'
            else
                result = "#{arr[0].floor}'-#{arr[1].floor} #{inch_frac}"+'"'
            end
        end
        return result
    end

    #=======================================
  # Convert Float to Feet
  #  rounded to nearest foot
  #=======================================
  def feet
      feet = (self/12).round(0).to_s
        result = feet +"'-0"
      return result+'"'
  end    

    #=======================================
  # Convert Float to Decimal Feet
  #  rounded to 3 decimal places
  #=======================================
  def decimal_feet
      feet = (self/12).round(3).to_s + "'"
      return feet
  end    

    #=======================================
  # Convert Float to Inches-Fractions
  #  Formats are:
  #    1/16"
  #    1 1/16"
  #    1"
  # nDivisor can be any integer between
  #    1 and 32.  Most common are:
  #               1,2,4,8,16 & 32
  #=======================================
  def inches(nDivisor)
      inches = self.floor
    if inches > 0.00
      frac = (self.remainder(inches)*nDivisor).round.quo(nDivisor)
    else
      frac = (self * nDivisor).round.quo(nDivisor)
    end
      if frac == 1
          result = "#{inches + 1}"
      elsif frac == 0 
          result = "#{inches}"
      else
          result = "#{inches} #{frac}"
      end
      return result.gsub(" ","-")+'"'
  end    

    #=================================================================
    # Get the SqRt of a number to n significant places
    #=================================================================
    def sqrt(n)
      a = self
        x = 1.00000
        while (x*x) < a
          x = x+0.00001
        end
        return x.round(n)
    end
    
  #=================================================================
    # Display a decimal value as a text string to (n) significant places
    #    syntax:  nvalue.sig(n)
    #    example: x = 65.375
    #             s = x.sig(4) ->  '65.3750'
    #    example: x = 65.25
    #             s = x.sig(3) ->  '65.250'
    #=================================================================
    def sig(n)
        nPad = self.round().to_s.length + n + 1
        result = self.round(n).to_s.ljust(nPad,"0")
        return result
    end

    #=================================================================
    # Convert millimeters to meters & display to (n) significant places
    #    syntax:  nvalue.meters(n)
    #    example: x = 6543
    #             s = x.meters(3) ->  '65.430 m'
    #    example: x = 650
    #             s = x.meters(3) ->  '6.500 m'
    #=================================================================
    def meters(n)
        if $Units.nil?
            nvalue = self
        elsif $Units == "Imperial"
            nvalue = self*2.54
        elsif $Units == "Metric"
            nvalue = self
        else
            nvalue = self
        end
        if n > 3
            n = 3
        elsif n < 0
            n = 0
        end
        m = nvalue/100
        result = m.sig(n).to_s + " m"
        return result
    end

end


 

  • Upvote 1
Link to comment
Share on other sites

40 minutes ago, tlinder said:

I'm am trying to read it from my local so I don't have to open every CA file and update them 1 by 1. We have hundreds of files.

wouldn't you have to open every file anyway to actually use the new functions you wish to define in the .rb file?

Link to comment
Share on other sites

Quote

Here's a sample rb file that has a series of defined methods.  Note that I no longer use this since it's problematical to update with each new version of chief.

Thank you Joe I will do some more research I this. I appreciate all your help!

Link to comment
Share on other sites

1 hour ago, jasonn1234 said:

wouldn't you have to open every file anyway to actually use the new functions you wish to define in the .rb file?

Initially yes, but for future updates I can just change the macro on the .rb file and it automatically updates the file when they are opened. 

Link to comment
Share on other sites

I'm confused. 

 

You need some ruby in each plan that requires (or loads) an external file. The videos will show a way to do this automatically.

 

You need to add some ruby (call a macro) to each object that uses the ruby code that you read in via require. Once this is done, changes in the external file will be reflected in the plan when it's opened.

 

 

These videos are showing the Number Formatter, but they also show what I think you are trying to do. Setting up an external file, or files containing your ruby so they may be updated independently of the plan file.

 

https://www.youtube.com/watch?v=LyP2Dfv9_oY&list=PL2B3hmDXZZU_zaGosj827usU9xoqrssQj&index=4&t=14s

 

https://www.youtube.com/watch?v=QRYfF1qRFAI&list=PL2B3hmDXZZU_zaGosj827usU9xoqrssQj&index=5

 

Link to comment
Share on other sites

I'm curious about the macro. If the rafter length is 96", the macro returns 10. Length of 95" returns 8. 

Are you looking for standard lumber lengths?

 

 

And here is a simpler version of your code. Not suggesting it's better.

 

rafter_length = (length.to_f.round / 12) + 1

if rafter_length.even? then

  rafter_length

else

  rafter_length + 1

end

 

 

Or even less.

 

rafter_length = (length.to_f.round / 12) + 1

rafter_length.even? ? rafter_length : rafter_length + 1

 

 

This one returns 8 when the length is 96, 10 when it's 120 etc.

 

# returns length as a multiple of 2'

 

r = (length/12).to_f.ceil # gets feet, converts to float, rounds up to the next whole number

 

r.odd? ? (r += 1) : r # add 1 if the number is odd

Link to comment
Share on other sites

  • Solution

I would suggest making a handful of changes to your current approach:

  1. Add your desired folder to the $LOAD_PATH OR place the desired file inside your currently defined $LOAD_PATH.  This way you can just use a file name instead of having to use the whole folder structure.
  2. Define a method inside your rb file
  3. Use require as Joe already mentioned instead of using File.read
  4. Call your defined method inside your Chief macro.

All said and done, it would look more like this (using your originally supplied example):

 

Macro: In CA

require 'scope1'

my_method

 

 

Output: from text stored on a local drive

def my_method

 

rafter_length = (length.to_f.round / 12) + 1

convert_to_int =  rafter_length.even?

case
  when convert_to_int == true
  resut = rafter_length

  when convert_to_int == false
  result = rafter_length +1
end

 

end

 

NOTE:  There are other potential approaches and corrections that could be made as well, but I wanted to stay as close as reasonably possible to your original attempt.

Link to comment
Share on other sites

I think there's a bit more that needs to be done to make it work correctly:

 

Macro: In CA

require 'scope1'

my_method(length)

 

 

Output: from text stored on a local drive

def my_method(x)

 

   rafter_length = (self.to_f.round / 12) + 1

   convert_to_int =  rafter_length.even?

   case
      when convert_to_int == true
        result = rafter_length

      when convert_to_int == false
        result = rafter_length +1
    end

 

end

 

Unless I'm wrong, the parmeter length needs to be passed to my_method in order for the method to know what's being analyzed.  

 

Link to comment
Share on other sites

3 hours ago, solver said:

rafter_length = (length.to_f.round / 12) + 1

rafter_length.even? ? rafter_length : rafter_length + 1

Thank you for the easier format and the YouTube videos. You gained yourself a new subscriber!

 

Quote

Are you looking for standard lumber lengths?

Yes I'm just trying to have the standard lumber lengths populate in the rafter labels.

Link to comment
Share on other sites

 

14 minutes ago, Joe_Carrick said:

Macro: In CA

require 'scope1'

my_method(length)

 

 

Output: from text stored on a local drive

def my_method(x)

 

   rafter_length = (self.to_f.round / 12) + 1

   convert_to_int =  rafter_length.even?

   case
      when convert_to_int == true
        result = rafter_length

      when convert_to_int == false
        result = rafter_length +1
    end

 

end

Joe and Michael

I tried both of those approaches and I wasn't able to get the right output in Chief.

Link to comment
Share on other sites

Just now, tlinder said:

 

Joe and Michael

I tried both of those approaches and I wasn't able to get the right output in Chief.

 

Did you set the macro to Evaluated:Owner?  And did you move your script to a folder in the $LOAD_PATH or adjust the $LOAD_PATH to add your desired folder?

Link to comment
Share on other sites

5 minutes ago, Alaskan_Son said:

 

Did you set the macro to Evaluated:Owner?  And did you move your script to a folder in the $LOAD_PATH or adjust the $LOAD_PATH to add your desired folder?

Are you saying to create a folder and name it $LOAD_PATH? I'm not sure what you mean.

Link to comment
Share on other sites

2 minutes ago, solver said:

 

What did you get?

Evaluation Error: Ruby SecurityError: Insecure operation - require

Stack Trace:

from (eval):2:in `block (3 levels) in <main>'

from (eval):1:in `instance_eval'

from (eval):1:in `block (2 levels) in <main>'

from eval:9:in `eval'

from eval:9:in `block (2 levels) in <main>'

from eval:3:in `loop'

from eval:3:in `block in <main>'

Link to comment
Share on other sites

33 minutes ago, Joe_Carrick said:

Unless I'm wrong, the parmeter length needs to be passed to my_method in order for the method to know what's being analyzed. 

 

1 minute ago, Joe_Carrick said:

You probably need to set the Ruby Safe Level to 1.  CA by default sets it at 2 which doesn't allow some things to work.

 

Neither of these things are true.  You can indeed define and call a method with no arguments, and if the file is a valid rb file located within the $LOAD_PATH, you can even have a Safe Level of 4 and it should still work.

Link to comment
Share on other sites

8 minutes ago, Alaskan_Son said:

 

 

Neither of these things are true.  You can indeed define and call a method with no arguments, and if the file is a valid rb file located within the $LOAD_PATH, you can even have a Safe Level of 4 and it should still work.

Agreed- except that AFAIK, Chief's default Safe Level has always been 2

 

I do have some macros that create, read and write files.  Some of those require a Safe Level of "0".

Link to comment
Share on other sites

For rb files that you wish to use in multiple versions of Chief you will need to make sure you copy them to the current version's $LOAD_PATH.

-or-

put them in a common file and edit the $LOAD_PATH in the current version of Chief.  I'm pretty sure you can have multiple paths separated by simi-colons

Link to comment
Share on other sites

If I remember correctly, i think I tested the load path about 12 months ago and could not get it to work. Instead If I remember correctly, I put a function in the "tutorial.rb" file and it worked.

 

Although tutorial.rb is distributed by CA so it will be overwritten on installation, probably ok for testing but not long term

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

  • Member Statistics

    32367
    Total Members
    9156
    Most Online
    Echodrewer
    Newest Member
    Echodrewer
    Joined
  • Similar Content

    • By Allen43
      I'll new to Chief and have learned that this form might be one of the best resources I have ever used. I am trying to streamline my design process and to do that I would love to be able to change cabinet ends to finished or paneled faster and easier. I tried to make a SP to do this, but I couldn't figure it out. I also thought that there might be a way to do this with macros is a SP, but I know even less about macros than I do Chief.
       
      Any help is appreciated, and if it's not possible that's fine I'll know not to spend more time on this.
    • By wazzubrad
      Guys, I am starting to find some of the limitations that I see discussed in the forums and am wondering if this is one of those. The current plan I am working on has various footing widths and depths specified by the engineer for the foundation walls. While trying to create a wall schedule that will show each wall based on footing width and depth and when I look at the available macro's under Object Properties for a macro I don't see anything specific to the footing depth. Anyone know if this property exists for a foundation wall?
       

    • By Renerabbitt
      Do you have 10+ years in the software and wonder if you've been missing some tips and tricks? Have you been able to break the 15 hour condoc set?
      Maybe you are a proficient user that wants to know everything that there is to know in Chief.
      Rendering, Automation, Resources, Symbols, Quick Tools, Style Pallets, PDF Tools, Templates, and more.

      We believe in lifting the community up. All of our tools and resources are available to you. With training that can be personal, team oriented, prerecorded, livestreamed, interactive. We offer training in over 15 softwares from Drafting and Detailing to Modeling, Advanced Texturing, Procedural Workflows, Node Based Design, Macro Creations, DAMs, Automation, VR Workflows, Streaming Overlays and Masks and much much more. Tell us your needs and we will connect you with the package or the right resource.

      Some example learning modules:
      Concentric Jump your dimension strings
      Enter-input your jumps and Enter-close your DBX's
      Snap jump your door widths, concentric jump your windows
      Alt behavior tips, contain-selection and deselection workflows with tool restrictions. 
      Tons of cabinet tools and tips, including custom one-off parametrically modelled vanities and more.
      Custom Toolbar Icons and Custom Library Objects.
      Toolbar Switching Tricks and Library workflows


       
      Other Offer Services Posts:
       
    • By DRyeHD
      I have a total of 14 possible layout pages I use.  I have my layout pages defined using the # sign.  On my "0" layout page I use %page.print% for the page number and %numpages% to get the total number of pages.  I don't always use all 14 pages but would rather not delete them from the client layout file in case they decide they want additional pages later.  So, as it is, even if I just need six pages the number 14 displays (see attachment).  Is there a way to get that macro to reflect the number of pages used in my layout schedule or the number of actual pages that I will print?  Also, is there an easier way to select which pages display in the layout table than opening each layout page and editing each one's layout page information (like a list of layout pages you could pull up and select/deselect the two checkboxes on this DBX?

    • By buzzsaw204
      hi all,
      i have a Library of Ruby macro that was custom coded for me few years back.
      some the task/script is not working anymore cuz of the X12 upgrade.
      i would like have this Library upgraded and refresh the Code to the X12 version. and get it working again.
       
      the Library was very well and beautifully coded by another guru/ruby master.
      But unfortunately, iam unable reach the original programmer to redo this project.
       
      im looking for someone that could help and take over and upgrade this Library.
       
      Please contact me.