Author Topic: Ceiling Tile Grid routine for Lighting  (Read 7076 times)

0 Members and 1 Guest are viewing this topic.

nivuahc

  • Guest
Ceiling Tile Grid routine for Lighting
« on: February 22, 2005, 10:33:41 AM »
First of all, let me start off by saying that I was reluctant to post this code here for a number of reasons. First, and foremost, I'm certain that there is a better way, a more effecient way, and a cleaner way to accomplish what this code accomplishes. Second, I threw this code together one afternoon in frustration and I haven't even had an opportunity to comment it all correctly. It's embarrasing.

So, having said all of that, here it is. Someone asked a few days ago about a routine for drawing acoustical ceiling tile grids for a lighting layout and this is what I use. Quite often we get drawings from the architect and the layout that they have for the ceiling grid is so horribly bad that we end up having to draw it all anyway.

What this code does
This is two routines that do, essentially, the same thing. They could be combined into one routine, I know, but, like I said, this was a 'quick-n-dirty' bit of code. The only difference between the two routines is that one of them draws the grid at an angle (for rooms situated at an angle, obviously) and one of them does not.

You have the option of drawing a 'frame' around the room (a rectangle on the same layer as the grid) or not, and the routine centers the 24" X 24" grid in the room (much like the guy who will actually be installing the tiles will do).

That's all well and good until you realise that not all rooms are square or rectangular shaped. And that's why the option is there for the frame.

Normally, when we draw these 'by hand' we draw a polygon frame (in the case of a non-rectangular room) around the room, draw a line across the room vertically and horizontally, then copy or offset those lines by 24 inches. Then we center the grid and trim off the excess. That process goes much quicker if the room is rectangular or square in shape, but it's still a very time consuming bit of work. For example, the project that prompted me to write this was a middle school with somewhere in the neighborhood of 60 rooms and corridors that our loving architect revised on a daily basis. Every day we had to 'clean up' the architects drawings so that we could use them. The process of drawing the ceiling grids, alone, took most of the day.

These routines, believe it or not, save us countless hours of work because the most tedious of the above mentioned tasks are eliminated. The only thing left for the user to do is trim off the excess of a non-rectangular room.

How I use these routines
For a square or rectangular room (not at an angle), in the words of the band Saliva: click, click, BOOM!

Done.

For a square or rectangular room (at an angle): click, click, click, BOOM!

I use the routine with the argument e_frame set to TRUE and it does all of the work.

For a non-rectangular room I draw a polygon frame around the limits of the room and I run the routine with the argument e_frame set to FALSE. It draws the grid, centered in the room, then I trim the excess using my frame as the boundary.

For a real world example of how that works consider the middle school I mentioned above. I can do the whole school in about an hour compared to all day doing it 'by hand'.

What I have listed is, first, the format that I use to call these routines from our menu. The routines are stored in our MNL file along with the little bitty routine elecLayers that I included (it's used in these routines).

Where these routines could go
One of the things I plan to do one of these days when I have time (HA!) is to try to combine this all into one nice little routine that does everything like this:

The user is first prompted for what type of frame they want to draw, polygon or rectangle. If they choose rectangle, run the routine pretty much as is. If they choose polygon, prompt for each point around the frame and, when the user us finished, draw the grid then use the polygon they created to trim the excess, if any.

Why it doesn't do that already
Like I said, quick-n-dirty. Compared to what we used to do, this is heaven as it is right now. I'm not given much time to actually write code at work, I have to sneak it in. On those rare occasions where I do get time, I end up having only enough time to throw together something quick-n-dirty.

Most of my coding happens on my personal time, like during lunch or after work. Right now this works better than anything my users have ever had so there isn't a valid reason (in my boss' eyes) for me to spend anymore time on it. None of the users here really appreciate the code I write anyway, so it's difficult for me to care how easy I can make things on them. I know, bad attitude and all...

Anyway, here it is, ask any questions if you like, hack away at it if you want, critique it to it's last bit if you like, copy it, put your name on it, tell everyone else you wrote it and sell it for a million dollars if it makes you happy. :)


Code: [Select]

;;==========================================================================================
;; Commands, as they appear in the menu
;;==========================================================================================

ID_EGridF    [EGrid with Frame]^C^C(setq e_frame T);egrid;
ID_EGrid     [EGrid w/o Frame]^C^C(setq e_frame F);egrid;
ID_EGridA    [Angled EGrid with Frame]^C^C(setq e_frame T);a_egrid;
ID_EGridAx   [Angled EGrid w/o Frame]^C^C(setq e_frame F);a_egrid;



;;==========================================================================================
;; elecLayers
;;==========================================================================================
(defun elecLayers (x)
(and (tblsearch "layer" x))
)




;;==========================================================================================
;; EGRID
;;==========================================================================================
(defun c:egrid (/   pt_1      pt_2 h_dist    h_count
h_pt_1   h_pt_a     h_diff v_dist    v_count
v_pt_1   v_pt_a     v_diff user_osnap user_layer
      )
 
  (setq pt_1 (getpoint "\nSelect LOWER-LEFT corner of room"))
  (setq pt_2 (getcorner pt_1 "\nSelect UPPER-RIGHT corner of room"))

  (setq h_dist (- (car pt_2) (car pt_1)))
  ;; horizontal length of the rectangle
  (setq v_dist (- (cadr pt_2) (cadr pt_1)))
  ;; vertical length of the rectangle

  (setq h_count (atoi (rtos (/ h_dist 24.0) 2)))
  ;; the number of 24 inch spaces, horizontally
  (setq v_count (atoi (rtos (/ v_dist 24.0) 2)))
  ;; the number of 24 inch spaces, vertically

 
  (if (= 24 (/ h_dist h_count))
    ;; alright, here is where we check to see if the number of spaces that we came up with
    ;; is divisible by 24. Because, if it isn't, we need to adjust our starting points to
    ;; begin the drawing of our grid. If it is, then we need to subtract 1 from the total
    ;; because, if not, a line will be drawn on the far wall (vertically or horizontally)
    ;; where it is equally divisible and we want to eliminate that clutter.    
    (progn
      (setq h_count (1- h_count))
      (setq v_pt_1 pt_1)
    )
    ;; okay, everything is equally divisible by 24 so subtract 1 off of the count total and
    ;; our VERTICAL grid lines will be centered, horizontally.    
    (progn
      ;; Oops, not so good now. Since our distance isn't divisible by 24 our grid needs to
      ;; be centered, horizontally, for us.      
      (setq h_diff (- 24 (/ (- h_dist (* h_count 24)) 2)))
      ;; set a variable for the difference by multiplying our count by 24, subtracting that
      ;; number from our overall distance, taking the number we come up with, and dividing
      ;; it by two. Then, subtract that number from 24 so that we know where to actually
      ;; start drawing our VERTICAL lines.      
      (if (< 12 h_diff)
(progn
 (setq h_diff (+ 12 h_diff))
 (setq h_count (1- h_count))
)
(progn)
      )
      ;; if the number we came up with above is less than 12 it is most likely not going to
      ;; look all that great as a finished product. A 2 inch sliver of ceiling tile is not
      ;; only ugly, it's difficult to install. Therefore, we can add 12 inches (oddly enough
      ;; that's half the distance across a 2 foot square of tile) and add it to our starting
      ;; point. If we're gonna do that, however, we need to draw 1 less line, overall.
      (setq h_count (1+ h_count))
      (setq v_pt_1 (subst (+ 24 (- (car pt_1) h_diff)) (car pt_1) pt_1))
    )
  )

  (if (= 24 (/ v_dist v_count))
    (progn
      (setq v_count (1- v_count))
      (setq h_pt_1 pt_1)
    )
    (progn
      (setq v_diff (- 24 (/ (- v_dist (* v_count 24)) 2)))
      (if (< 12 v_diff)
(progn
 (setq v_diff (+ 12 v_diff))
 (setq v_count (1- v_count))
)
(progn)
      )
      (setq v_count (1+ v_count))
      (setq
h_pt_1 (subst (+ 24 (- (cadr pt_1) v_diff)) (cadr pt_1) pt_1)
      )
    )
  )

  (setq user_osnap (getvar "osmode"))
  (setq user_layer (getvar "clayer"))

  (setvar "osmode" 0)
  (if (/= (elecLayers "egrid") T)
    (command "-layer" "n" "egrid" "c" "41" "egrid" "")
  )
  (setvar "clayer" "egrid")

  (repeat v_count
    (setq h_pt_a (subst (+ 24.0 (cadr h_pt_1)) (cadr h_pt_1) h_pt_1))
    (setq h_pt_b (subst (+ h_dist (car h_pt_a)) (car h_pt_a) h_pt_a))
    (command "line" h_pt_a h_pt_b "")
    (setq h_pt_1 h_pt_a)
  )

  (repeat h_count
    (setq v_pt_a (subst (+ 24.0 (car v_pt_1)) (car v_pt_1) v_pt_1))
    (setq v_pt_b (subst (+ v_dist (cadr v_pt_a)) (cadr v_pt_a) v_pt_a))
    (command "line" v_pt_a v_pt_b "")
    (setq v_pt_1 v_pt_a)
  )
  (if (= e_frame T)
    (command "rectangle" pt_1 pt_2))

  (setvar "osmode" user_osnap)
  (setvar "clayer" user_layer)
)



;;==========================================================================================
;; A_EGRID
;;==========================================================================================
(defun c:a_egrid (/     pt_1 pt_2   pt_3
 h_dist     h_count h_pt_1   h_pt_a
 h_diff     v_dist v_count   h_ang
 v_pt_1     v_pt_a v_diff   user_osnap
 user_layer user_units egrid_ss
)

  (setq user_units (getvar "lunits"))
  (setvar "lunits" 2)

  (setq pt_1 (getpoint "\nSelect LOWER-LEFT corner of room"))
  (setq pt_2 (getpoint pt_1 "\nSelect LOWER-RIGHT corner of room"))
  (setq pt_3 (getpoint pt_2 "\nSelect UPPER-RIGHT corner of room"))

  (setq h_dist (distance pt_1 pt_2))
  (setq v_dist (distance pt_2 pt_3))
  (setq h_ang (rtd (angle pt_1 pt_2)))

  (setq h_count (atoi (rtos (/ h_dist 24.0) 2)))
  (setq v_count (atoi (rtos (/ v_dist 24.0) 2)))

  (if (= 24 (/ h_dist h_count))
    (progn
      (setq h_count (1- h_count))
      (setq v_pt_1 pt_1)
    )
    (progn
      (setq h_diff (- 24 (/ (- h_dist (* h_count 24)) 2)))
      (if (< 12 h_diff)
(progn
 (setq h_diff (+ 12 h_diff))
 (setq h_count (1- h_count))
)
(progn)
      )
      (setq h_count (1+ h_count))
      (setq v_pt_1 (subst (+ 24 (- (car pt_1) h_diff)) (car pt_1) pt_1))
    )
  )

  (if (= 24 (/ v_dist v_count))
    (progn
      (setq v_count (1- v_count))
      (setq h_pt_1 pt_1)
    )
    (progn
      (setq v_diff (- 24 (/ (- v_dist (* v_count 24)) 2)))
      (if (< 12 v_diff)
(progn
 (setq v_diff (+ 12 v_diff))
 (setq v_count (1- v_count))
)
(progn)
      )
      (setq v_count (1+ v_count))
      (setq
h_pt_1 (subst (+ 24 (- (cadr pt_1) v_diff)) (cadr pt_1) pt_1)
      )
    )
  )

  (setq user_osnap (getvar "osmode"))
  (setq user_layer (getvar "clayer"))

  (setvar "osmode" 0)
  (if (/= (elecLayers "egrid") T)
    (command "-layer" "n" "egrid" "c" "41" "egrid" "")
  )
  (setvar "clayer" "egrid")
  (setq egrid_ss (ssadd))

  (repeat v_count
    (setq h_pt_a (subst (+ 24.0 (cadr h_pt_1)) (cadr h_pt_1) h_pt_1))
    (setq h_pt_b (subst (+ h_dist (car h_pt_a)) (car h_pt_a) h_pt_a))
    (command "line" h_pt_a h_pt_b "")
    (ssadd (entlast) egrid_ss)
    (setq h_pt_1 h_pt_a)
  )

  (repeat h_count
    (setq v_pt_a (subst (+ 24.0 (car v_pt_1)) (car v_pt_1) v_pt_1))
    (setq v_pt_b (subst (+ v_dist (cadr v_pt_a)) (cadr v_pt_a) v_pt_a))
    (command "line" v_pt_a v_pt_b "")
    (ssadd (entlast) egrid_ss)
    (setq v_pt_1 v_pt_a)
  )
  (command "rotate" egrid_ss "" pt_1 "r" pt_1 "@1<0" pt_2)

  (if (= e_frame T)
    (progn
      (command "pline"
      pt_1
      (strcat "@" (rtos h_dist) "<0")
      (strcat "@" (rtos v_dist) "<90")
      (strcat "@" (rtos h_dist) "<180")
      "c"
      )
      (command "rotate" "l" "" pt_1 "r" pt_1 "@1<0" pt_2)
    )
  )

  (setvar "lunits" user_units)
  (setvar "osmode" user_osnap)
  (setvar "clayer" user_layer)
)

;;===================================================================

hyposmurf

  • Guest
Ceiling Tile Grid routine for Lighting
« Reply #1 on: February 22, 2005, 11:04:22 AM »
Why not create a user defined hatch swatch pattern with double selected and a spacing of 24?That will create a ceiling grid in a rectangular room or just define the boundary if its irregular.

nivuahc

  • Guest
Ceiling Tile Grid routine for Lighting
« Reply #2 on: February 22, 2005, 11:07:31 AM »
Quote from: hyposmurf
Why not create a user defined hatch swatch pattern with double selected and a spacing of 24?That will create a ceiling grid in a rectangular room or just define the boundary if its irregular.


That was what I tried first. AutoCAD has an odd way of determining the 'center' of a room and it never, ever, ever worked out right.   :roll:

TimSpangler

  • Water Moccasin
  • Posts: 2010
  • CAD Naked!!
Ceiling Tile Grid routine for Lighting
« Reply #3 on: February 22, 2005, 11:10:04 AM »
nivuahc,

I tried it and it works :) .  I had recently ran into the same situation and did the dame thing but took a differant approach.  I used costom hatch patterns,

Here it is

  Give it a whirl
ACA 2015 - Windows 7 Pro
All Comments and Content by TimSpangler, Copyright © 2016

nivuahc

  • Guest
Ceiling Tile Grid routine for Lighting
« Reply #4 on: February 22, 2005, 11:43:46 AM »
This is what I get



Notice how the grid isn't centered (horizontally from wall to wall) and how the door becomes a problem? Other than that it works great!

Nice bit of work on the DCL, btw.  8)

hudster

  • Gator
  • Posts: 2848
Ceiling Tile Grid routine for Lighting
« Reply #5 on: February 22, 2005, 11:44:29 AM »
I use this script to insert a 600x600 ceiling grid.

Code: [Select]
^C^Csnapbase;int;\hatch;u;0;600;y;\;snapbase;0,0;

You guys really need to get metric. :D
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

nivuahc

  • Guest
Ceiling Tile Grid routine for Lighting
« Reply #6 on: February 22, 2005, 11:51:31 AM »
Well, now, that works so far... not too shabby  8)

hudster

  • Gator
  • Posts: 2848
Ceiling Tile Grid routine for Lighting
« Reply #7 on: February 22, 2005, 12:00:54 PM »
nivuahc, when I try your angled grid, I get a the following error,

Code: [Select]
error: no function definition: RTD

Is RTD part of another lisp you have?
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

nivuahc

  • Guest
Ceiling Tile Grid routine for Lighting
« Reply #8 on: February 22, 2005, 12:53:45 PM »
oop!

Code: [Select]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Convert radians to degrees
(defun rtd (var) (/ (* var 180.0) pi))


This is what I'm talking about. I never, once, considered changing my snapbase.

I need to redo this whole thing, make it simpler.

hyposmurf

  • Guest
Ceiling Tile Grid routine for Lighting
« Reply #9 on: February 22, 2005, 01:43:49 PM »
Quote from: nivuahc


Notice how the grid isn't centered (horizontally from wall to wall) and how the door becomes a problem? Other than that it works great!



Ive had the same problem before and I know how long it takes to draw and trim a grid off multiple irregular shaped rooms,all that before youve started adding your own equipment.Wouldnt it be nice if you could just pan the hatches about within the boundary until they were positioned correctly.You can pan them but they will leave gaps around the sides of the moved hatch,need some type of autofill.Maybe itll be in the 2006 version.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Ceiling Tile Grid routine for Lighting
« Reply #10 on: February 22, 2005, 03:42:48 PM »
How about a routine where you picked the hatch and then picked points for a new snap base while
the hatch is redrawn until you hit enter.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

whdjr

  • Guest
Ceiling Tile Grid routine for Lighting
« Reply #11 on: February 23, 2005, 02:53:37 PM »
If you hatch an area and use the option to supply a boundary for the hatch, then you can move the hatch and the boundary to align the hatch properly you can then move the boundary only and the hatch stays where it is and associative.

Crank

  • Water Moccasin
  • Posts: 1503
Ceiling Tile Grid routine for Lighting
« Reply #12 on: February 24, 2005, 05:14:26 AM »
I think CAB's method is better: Just move the snapbase and update the hatch.
Vault Professional 2023     +     AEC Collection