乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
楼主: drew4748

[编程交流] 块间距lisp

[复制链接]

15

主题

315

帖子

361

银币

初来乍到

Rank: 1

铜币
25
发表于 2022-7-5 17:54:40 | 显示全部楼层
I added an attribute "BACK" to the panel.
 
The back ballasts come 200 mm from the bottom; the top ballasts come 600 mm from the bottom.
You can change this with these commands:
(+ 200.0 y_value) and (+ 600.0 y_value)
 
The code is now this:
  1. ;; @file: draw ballasts on solar panels, depending on the properties of the roof regions;; @author: Emmanuel Delay - emmanueldelay@gmail.com; load extra recources(vl-load-com)(defun ballast ( / blocks x_values sorted_indexes block spacing x_pointer x_pointer_back lft rgt width_panel y_value)  (princ "\nSelect the solar panel blocks (cross select)") (setq    i 0   spacing 0.0   x_pointer 0.0                                                       ;; x_pointer is like the needle of a turn table.  We set it to the x of the left panel block, then it only increases untill we get to the right panel    x_pointer_back 0.0   x_values (list)   blocks (ssget ":N"     ;; client makes a cross select     (list        (cons 0 "INSERT")     )   ) ) ;; we read the y-value of the first panel (setq y_value (nth 2 (assoc 10 (entget (ssname blocks 0)))  ))  ;; we make an array (list) containing the x-value of the insert point  (repeat (sslength blocks)   (setq x_values (append x_values (list     (cadr (assoc 10 (entget (ssname blocks i))))  ;; returns the insert point, x-value   )))   (setq i (+ i 1)) )  ;; we sort this last list, from left to right.  sorted_indexes contains the index (to be used in the "nth" and "ssname" function  ) (setq sorted_indexes (vl-sort-i x_values    (function (lambda (e1 e2) (< e1 e2))) )) ;; we set x_pointer to the x-value of the left panel (setq x_pointer (nth (nth 0 sorted_indexes) x_values)) (setq x_pointer_back (nth (nth 0 sorted_indexes) x_values))  ;; same for the back pointer  ;; calculate the width of the panel  (setq width_panel (- (nth (nth 1 sorted_indexes) x_values) (nth (nth 0 sorted_indexes) x_values) ))  ;; we loop over sorted_indexes. (setq i 0) (repeat (length sorted_indexes)   (setq block (VLAX-ENAME->VLA-OBJECT (ssname blocks (nth i sorted_indexes))))   ;; set left and right point of the panel   (setq      lft (nth (nth i sorted_indexes) x_values)     rgt (+ lft width_panel)   )    ;; we look for the "SPACING" attribute   (foreach Attribute (vlax-invoke Block "GetAttributes")     (if (= (vla-get-TagString Attribute) "SPACING")       (progn         (setq spacing (atof (vla-get-TextString Attribute)))         ;;         (while (< x_pointer rgt)           (progn             (AT:InsertBlock "ballast" (list x_pointer (+ 600.0 y_value)) 1.0 1.0 0.0)             (setq x_pointer (+ x_pointer spacing))           )         )         (princ "\n")       )     )   )   ;; we look for the "BACK" attribute   (foreach Attribute (vlax-invoke Block "GetAttributes")     (if (= (vla-get-TagString Attribute) "BACK")       (progn         (setq spacing (atof (vla-get-TextString Attribute)))         ;;         (while (< x_pointer_back rgt)           (progn             (AT:InsertBlock "ballast" (list x_pointer_back (+ 200.0 y_value)) 1.0 1.0 0.0)             (setq x_pointer_back (+ x_pointer_back spacing))           )         )         (princ "\n")       )     )   )      (setq i (+ i 1)) ));;; Insert block into drawing;;; #Name - name of block;;; #InsPt - insert point;;; #XScale - block X scale;;; #YScale - block Y scale;;; #Rot - block rotation;;; Alan J. Thompson, 04.21.09(defun AT:InsertBlock (#Name #InsPt #XScale #YScale #Rot) (if (or (tblsearch "block" #Name)         (findfile #Name)     ) ;_ or   (vla-insertblock     ((if (eq (getvar "cvport") 1)        vla-get-paperspace        vla-get-modelspace      ) ;_ if       (vla-get-ActiveDocument         (vlax-get-acad-object)       ) ;_ vla-get-ActiveDocument     )     (vlax-3d-point #InsPt)     #Name     #XScale     #YScale     #XScale     #Rot   ) ;_ vla-insert-block ) ;_ if) ;_ defun;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defun c:ballast ( / ) (ballast) (princ))
spacing.dwg
回复

使用道具 举报

2

主题

15

帖子

13

银币

初来乍到

Rank: 1

铜币
10
发表于 2022-7-5 17:58:45 | 显示全部楼层
One more issue than I'm sure this is solved. When I changed the name of  the ballast block to "Ballast Block" which is the name of the block we  use, I get an "invalid table function argument(s): "Ballast Block"  "Ballast Block". When i changed the name in the first lsp you sent me,  it works fine with my block, but not with the routine which has both  rear and front spacing. Could you please shed some light on this. I attached both of the files. Maybe you can see something I cannot. Sorry I have never really done lsp routines before. Im sure this is an easy fix which I just can not see.Thank  you.ballast.lsp
ballast2.lsp
回复

使用道具 举报

15

主题

315

帖子

361

银币

初来乍到

Rank: 1

铜币
25
发表于 2022-7-5 18:00:27 | 显示全部楼层
No problem.
 
It's line 101 (of ballast2.lsp).
 
  1.   (if (or      (tblsearch "Ballast Block" #Name)     (findfile #Name)   ) ;_ or
should be
 
  1.   (if (or      (tblsearch "BLOCK" #Name)     (findfile #Name)   ) ;_ or
回复

使用道具 举报

2

主题

15

帖子

13

银币

初来乍到

Rank: 1

铜币
10
发表于 2022-7-5 18:06:19 | 显示全部楼层
 
So that last line where it says BLOCK is basically telling it to insert a block correct? Just trying to understand this better.
 
This works perfectly now that I have changed it. It will reduce my drafting time, and more importantly user errors significantly. Thank you.
回复

使用道具 举报

15

主题

315

帖子

361

银币

初来乍到

Rank: 1

铜币
25
发表于 2022-7-5 18:08:06 | 显示全部楼层
Autocad has a list (a table) of all the blocks, layers ... that are available.  
They might or might not have an instance drawn on the dwg, but they are available.
 
tblsearch searches in that list.  So, that would also be the function you need to see if you can set a layer
(tblsearch "LAYER" "MyLayer")
 
------
Let me tell you a a few things about LISP.
 
LISP has no operators.
 
Most programming languages do something like this:
 
a = b + 15
LISP does
(setq a (+ b 15))
 
- Opening a "(" means you start a function
"=" and "+" are just functions; in other languages they are operators; so they don't look like functions.
 
----
LISP looks most like javascript.  
That is to say: javascript was written to behave like LISP, but look like JAVA or C.
 
You can pass anything to any function.  You can pass the definition of a function to another function;
you have anonimous functions: lambda.
 
example
  1. (setq sorted_indexes (vl-sort-i x_values    (function (lambda (e1 e2) (< e1 e2))) ))
 
In javascript this would be something like
  1. sorted_indexes.sort(function(a, b) { return (a < b);});
 
So you can pass an anonimous function, each pair that is evaluated passes through that function.
In (most) other languages you can't do that.
 
Both in LISP and javascript there are no classes, no interfaces ... the function does it all.
回复

使用道具 举报

2

主题

15

帖子

13

银币

初来乍到

Rank: 1

铜币
10
发表于 2022-7-5 18:11:48 | 显示全部楼层
Let me just say I am very happy with this routine it works perfect, however I am having some troubles trying to update it. I cannot, and do not know how, to change where the routine inserts the blocks via the x coordinate. Also I am wondering as to why the block is grabbing the attribute from the next area as opposed to the area its in. Thanks in advance.
回复

使用道具 举报

1

主题

5

帖子

4

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-5 18:15:01 | 显示全部楼层
Hi Experts,
 
I am looking for a LISP routine which user defines an area (rectangle) and a block and 2 numbers x & y (array dimension) and the the routine place the amount of blocks inside the rectangle.
NB: the distance of block-edge of rectangle shall be distance of block-block divided by 2.
I need to use it to place an amount of lighting fixtures. lights must be away from walls half distance of light to light.
 
Thank you all.
回复

使用道具 举报

15

主题

315

帖子

361

银币

初来乍到

Rank: 1

铜币
25
发表于 2022-7-5 18:17:37 | 显示全部楼层
@Chemra
 
 
I'm not 100% sure what exactly you want, this is how I understand it:
 
Let's say you have a room: 12m (x-axis), 6m (y-axis), and you want 3 lamps along the x-axis, 2 lamps along the y-axis
This results in 6 lamps, inserted at (2.0  1.5), (2.0  4.5), (6.0  1.5), (6.0  4.5), (10.0  1.5), (10.0  4.5)
my idea is: I divide the room in 6 equal rectangles, each rectangle has a lamp in the middle of it.
 
 
 
Is that what you have in mind?
 
-----
 
Anyway, here is what I guess you want.
 
Included: 2 test functions, commands: "TEST" & "TEST2" (requires a block called "LAMP", feel free to change this value)
 
 
  1. ;; @see http://www.cadtutor.net/forum/showthread.php?88364-block-spacing-lisp&p=667173&viewfull=1#post667173;; I am looking for a LISP routine which user defines an area (rectangle) and a block and 2 numbers x & y (array dimension) ;;   and the the routine place the amount of blocks inside the rectangle.;; NB: the distance of block-edge of rectangle shall be distance of block-block divided by 2.;; I need to use it to place an amount of lighting fixtures. lights must be away from walls half distance of light to light.(vl-load-com);;; Insert block into drawing;;; #Name - name of block;;; #InsPt - insert point;;; #XScale - block X scale;;; #YScale - block Y scale;;; #Rot - block rotation;;; Alan J. Thompson, 04.21.09(defun AT:InsertBlock (#Name #InsPt #XScale #YScale #Rot) (if (or (tblsearch "block" #Name)         (findfile #Name)     ) ;_ or   (vla-insertblock     ((if (eq (getvar "cvport") 1)        vla-get-paperspace        vla-get-modelspace      ) ;_ if       (vla-get-ActiveDocument         (vlax-get-acad-object)       ) ;_ vla-get-ActiveDocument     )     (vlax-3d-point #InsPt)     #Name     #XScale     #YScale     #XScale     #Rot   ) ;_ vla-insert-block ) ;_ if) ;_ defun;; inserts a block.  This might be a function where you perform extra stuff, like fill attributes(defun insert_block (blockname x y / ) (AT:InsertBlock blockname (list x y) 1.0 1.0 0.0));; main function(defun fill_rectangle ( p1 p2 blockname cols rows / segment_x segment_y x y) (setq segment_x                ;; (x2 - x1) / cols   (/ (- (nth 0 p2) (nth 0 p1)) cols) ) (setq segment_y   (/ (- (nth 1 p2) (nth 1 p1)) rows) ) (setq    x 0   y 0 ) (repeat cols   (setq y 0)   (repeat rows     (insert_block         blockname        (+ (nth 0 p1) (/ segment_x 2 ) (* segment_x x ))  ;; insert point (x) + half segment length + X number full segment lengths       (+ (nth 1 p1) (/ segment_y 2 ) (* segment_y y ))     )     (setq y (+ y 1))   )   (setq x (+ x 1)) ));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; test function with hardcoded values, as example.;; This requires a block "LAMP"(defun c:test2 ( / p1 p2) (fill_rectangle   (list 0.0 0.0)   (list 12.0 6.0)   "LAMP"   3   2 ) (princ));; test function with user selected values.(defun c:test ( / p1 p2) (fill_rectangle      ;; user defines an area (rectangle)   (setq p1 (getpoint     "\nPoint 1, bottom-left: "))   (setq p2 (getcorner p1 "\nPoint 2, top-right: "))      ;; and a block   (getstring "\nBlock name: ")      ;; and 2 numbers x & y (array dimension)   (getint "\nX (number of colums) ")   (getint "\nY (number of rows) ")    ) (princ))
回复

使用道具 举报

1

主题

5

帖子

4

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-5 18:22:11 | 显示全部楼层
Brilliant thanks, You made my day
回复

使用道具 举报

1

主题

5

帖子

4

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-5 18:22:16 | 显示全部楼层
Hi Emmanuel,
 
I was trying to change the way of getting the block. I tried entsel, however, i still getting error, too many arguments. Any advice?
Thanks
 
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-13 08:34 , Processed in 0.951684 second(s), 70 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表