TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Prickle Farmer on August 31, 2016, 01:10:32 AM
-
Hi All
I am stumped again. I have a network of polylines. Many have common start and/or end points. I want to insert a block at each start/end but only if there is not already one there. I use ssget to collect all the entities at a point and process for a valid block. If not found, I insert one. The problem is that when I get to the start/end point of another polyline that coincides with the location of the block recently inserted, the ssget does not collect the previous block in the selection set. It is like that block doesn't exist until the program finishes, but I can see them being inserted. I have increased (setq ssa (ssget "C" pt pt)) to (setq ssa (ssget "C" (mapcar '- pt '(0.05 0.05 0)) (mapcar '+ pt '(0.05 0.05 0)))) to see if I can capture more...but to no avail. Any ideas?
-
To use (ssget "_C" ...) or (ssget "_W" ...) you have to show all bounds at screen.
I think the better way is to use selection set of all blocks and check - does some block inserted at specified point.
-
Consider pre processing the candidate end points first, ensuring there are no duplicates, then insert the blocks, one per unique endpoint.
-
Thanks kpblc. The problem is that the blocks do not exist before the program is rum
Thanks MP. You are suggesting building a list of points, checking that each new point is not already a member, then inserting the blocks at each point in the list. Hmm, good work around. I think that will work. Thanks.
-
Not a 'work around' but a logical solution. 8)
I assume you are using a version of the 'traveling salesman' algorithm?
http://goo.gl/LmOZSv
-
As you step through the polyline selection set, check if each start/end point is a member of an existing point list. If not, add to list and insert block.
-
Simplified examples to serve as food for thought --
Pre-processing a list of points to ensure each is unique on the basis of the fuzz value:
(defun _UniquePoints ( points fuzz / result )
(foreach p points
(if
(null
(vl-some
(function (lambda (p!) (equal p p! fuzz)))
points
)
)
(setq result (cons p result))
)
)
(reverse result)
)
That established ...
(foreach p (_UniquePoints candidate_points 0.001))
(_MakeBlockInstance p)
)
Alternatively, processing points on the fly (assuming vars in code below have been initialized) ...
(foreach p candidate_points
(if
(null
(vl-some
(function (lambda (p!) (equal p p! 0.001)))
processed_points
)
)
(progn
(setq processed_points (cons p processed_points))
(_MakeBlockInstance p)
)
)
)
Other means can be used to determine uniqueness, e.g. the distance function substituting a maxdist value for fuzz etc.
Anyway ... hope it helps some way ... coded fast hoping no errors ... cheers.
PS: Mods: Pls don't change the code tags, thanks.
-
Another spin on _UniquePoints just for fun:
(defun _UniquePoints ( points fuzz / p result )
(while points
(setq
result (cons (setq p (car points)) result)
points (vl-remove-if (function (lambda (p!) (equal p p! fuzz))) (cdr points))
)
)
(reverse result)
)
May be faster (guess) on large lists with lots of duplicates but hasn't been benched or tested. Cheers.
-
I thought there was still $1million for creating the "traveling salesman".
Thanks MP. The fuzz factor was just what I was thinking about. I checked my test drawing and found a misclose of 0.00000002 at one junction. I know this should not occur but I don't have "complete and supreme control" over my CAD operators. Such is life. Your code looks good. Thanks. I am still confused as to why ssget can't see objects inserted by my code. I must tell myself to get a life and move on!!
-
I am still confused as to why ssget can't see objects inserted by my code.
Since the result of the graphical ssget selection methods (i.e. C/F/W/CP/WP etc.) is determined by the objects visible in the drawing area at the time of evaluation, ssget will not obtain a selection of newly generated objects until the drawing area is redrawn, which will depend on the method you are using to insert your blocks.
-
on the subject of ssget & C filter, is there a way to combine with lock filter? I have success with
but not
the alternative is to create a list of locked layers and use a (-4 . "<NOT") filter by those layers, just wondered if I was missing something
Thanks - Dan
-
Thanks Lee. To me, that means that any lisp action can only apply to objects in the "display list" at the time of execution. I even tried peppering my code with a "regen" or two but that didn't work either. My problem has been solved by MP's suggestion. Thanks MP. I found similar code on your site too, Lee. Cheers Phil.
-
on the subject of ssget & C filter, is there a way to combine with lock filter? I have success with
but not
As far as I am aware, the :L mode string can only be used in conjunction with user selection mode strings (as opposed to automatic selection mode strings).
that means that any lisp action can only apply to objects in the "display list" at the time of execution.
No, this restriction only applies to graphical ssget selection methods (such as C/F/W/CP/WP etc.).
-
Glad you've a fix going forward PF. Thanks for chiming in with useful info (as usual) LM. Cheers all.
-
Glad you've a fix going forward PF. Thanks for chiming in with useful info (as usual) LM. Cheers all.
Cheers MP, a delight to see you posting again.
-
Thank you Lee, that's awesome of you to say. :)