Jump to content

Recommended Posts

Posted

The blocks that the pipe are "attached" to are all the same size, 12" when inserted in 1/8" scale, which is the same as dimscale 1. I was just stating that the blocks are drawn to size as 1/8", then they are scaled up and down from there. The way I was used to doing it was that dimscale of 96 was 1/8", but now dimscale 1 is the same as 1/8".

  • Replies 47
  • Created
  • Last Reply

Top Posters In This Topic

  • brawleyman

    22

  • pBe

    15

  • irneb

    9

  • Tharwat

    1

Top Posters In This Topic

Posted Images

Posted
The blocks that the pipe are "attached" to are all the same size, 12" when inserted in 1/8" scale, which is the same as dimscale 1. I was just stating that the blocks are drawn to size as 1/8", then they are scaled up and down from there. The way I was used to doing it was that dimscale of 96 was 1/8", but now dimscale 1 is the same as 1/8".

 

Alrighty then.. now take two aspirins ,draw 2" radius circle at 6" apart and a 6 " arc snap at the bottom quadrant of both circles on the screen and check this thread in the morning :)

Posted
Alrighty then.. now take two aspirins ,draw 2" radius circle at 6" apart and a 6 " arc snap at the bottom quadrant of both circles on the screen and check this thread in the morning :)

 

Will do, thanks pBe! I actually could do with some aspirins today... :)

Posted

You know ... if there are several block types you need to sort through, are they all the same size and general shape? Does the pipe always "join" them at 90 degree angles? If all the blocks are circular, then it might not matter about the angle. But if some of the blocks are say square - then a 45 degree pipe join would look weird. You could try using some code I saw somewhere which calculates the external border of the objects inside the block (I think it was called something like Wrap / ShrinkWrap), that way the routine could then figure out where the pipe intersects with the block's most external objects and extend/trim the pipe to that point.

 

I'm actually of the opinion you might want to try placing a wipeout / white (rgb 255,255,255) solid hatch inside the block definition, then bring all blocks to front. That way the pipe goes to the block's insertion point but gets hidden to show the same effect. Then all your code needs to do is modify the pipe's width and set the new lts & block scale. If you setup some parameters in your CTB you could even leave the pipe width=0 and have the CTB scale the pipe width for you, then you could change your block to be annotative and set your LTS / PSLTScale accordingly and you won't even need any lisp at all. Same applies to the pipe-tag, turn it into an attributed block and set it to be annotative - it might cause havoc if you don't filter it out of the routine (i.e. the pipe gets cut around the tag as well).

Posted
You know ... if there are several block types you need to sort through, are they all the same size and general shape? Does the pipe always "join" them at 90 degree angles? If all the blocks are circular, then it might not matter about the angle. But if some of the blocks are say square - then a 45 degree pipe join would look weird. You could try using some code I saw somewhere which calculates the external border of the objects inside the block (I think it was called something like Wrap), that way the routine could then figure out where the pipe intersects with the block's most external objects and extend/trim the pipe to that point.

 

I'm actually of the opinion you might want to try placing a wipeout / white (rgb 255,255,255) solid hatch inside the block definition, then bring all blocks to front. That way the pipe goes to the block's insertion point but gets hidden to show the same effect. Then all your code needs to do is modify the pipe's width and set the new lts & block scale. If you setup some parameters in your CTB you could even leave the pipe width=0 and have the CTB scale the pipe width for you, then you could change your block to be annotative and set your LTS / PSLTScale accordingly and you won't even need any lisp at all. Same applies to the pipe-tag, turn it into an attributed block and set it to be annotative - it might cause havoc if you don't filter it out of the routine (i.e. the pipe gets cut around the tag as well).

 

Some good suggestions, but things that I have already looked into and won't really work. Problem is that I have to use HydraCAD to create the pretty pipe with. Also, the sprinkler head blocks we use have 2 different sizes, 12" and 18" and pipe for the most part is run at 90 degree angles, but sometimes it may come in at any kind of angle. The fact that I have to use their routine to create it defeats the purpose of using wipeouts too. I do use wipeouts on a few of my symbols like keynotes, room names, grid bubbles and general notations.

 

I am just having to find ways to work around how HydraCAD works. The best way to accomplish what I am wanting is what pBe is working on for me... scale all blocks to new dimscale from insertion point, and find and scale all plines from their midpoint and shorten/lengthen depending on which way the scale is going.

Posted

I'm really sorry to hear that! Painful when something which is supposed to make your life easier actually ends up making other problems :glare:

 

Just a query to make the block selection a bit easier, are all the blocks always from a finite set? I.e. the block names are always the same, never some arb $Gable-garble block name. If so it might be a lot simpler to filter for those block names inside the ssget instead of trying to omit xrefs.

 

pBe ... sorry I'm not at an ACad so I can't check this (busy trying to get BricsCAD to work on Fedora 16-64bit, after I finally gave up on Win7 and it's constant crashes - 3rd time in a year that I need to reinstall the damned thing). Does the ActiveX method "IntersectWith" work on blocks as well? If so you won't need the ShrinkWrap idea, all you need to to find the closest intersection point to the pipe's midpoint.

Posted
I'm really sorry to hear that! Painful when something which is supposed to make your life easier actually ends up making other problems :glare:

 

Just a query to make the block selection a bit easier, are all the blocks always from a finite set? I.e. the block names are always the same, never some arb $Gable-garble block name. If so it might be a lot simpler to filter for those block names inside the ssget instead of trying to omit xrefs.

 

pBe ... sorry I'm not at an ACad so I can't check this (busy trying to get BricsCAD to work on Fedora 16-64bit, after I finally gave up on Win7 and it's constant crashes - 3rd time in a year that I need to reinstall the damned thing). Does the ActiveX method "IntersectWith" work on blocks as well? If so you won't need the ShrinkWrap idea, all you need to to find the closest intersection point to the pipe's midpoint.

 

For the most part they have certain names, but I was just trying to make it so that it would be dynamic and any blocks in model space would get scaled. As we work through our projects, we figure out different blocks and such that we can create and use, so it would be kind of a pain to have to remember to add those new block names each time we make new ones. It could be done, but I wouldn't like to do it that way if at all possible. The routine for pretty pipe is really nice, but I am just trying to make it to where just in case you have to change the scale AFTER the pipe has been created it can be done easily without having to delete and go through the process again of creating it, which takes a little while and also allows you to pick which lines are higher than others and insert break lines around.

Posted
The "easiest" way might be to use ssget's ":L" option to disallow selection of entities on locked layers..... I think the most efficient way might be to generate a list of block names which aren't xrefs

(tblnext). Then combine that into a comma seperated string for inclusion in ssget's filter list. That way you only need to check each block definition once

I concur :thumbsup:

Done

 

....(busy trying to get BricsCAD to work on Fedora 16-64bit, after I finally gave up on Win7 and it's constant crashes - 3rd time in a year that I need to reinstall the damned thing).

 

I feel your pain. :wink:

 

pBe ... Does the ActiveX method "IntersectWith" work on blocks as well?

Now that you mentioned it. I'm not so sure :lol:,

it gives you a point list if the blocks are the same, weird really...

 

Right now, the scaling of the plines doesn't work on every scale, but not sure why. :(

Fixed, i supplied a negative number.

 

. Find and scale ALL blocks and plines on a particular layer in model space....

And what Layer may that be?

Plines->

Blocks->

Does that also apply to XREFs? All layers on on a particualr layer? if so

 

block name. If so it might be a lot simpler to filter for those block names inside the ssget instead of trying to omit xrefs.

would be somewhat applicable, but using LAYER names and not block names. anyhoo the way the code is written now will take care of those issues...

 

Also, the sprinkler head blocks we use have 2 different sizes, 12" and 18"......

so when is the block 12" and when 18"? and also for the width? when is it "2" and "3"?

 

>>>>>>>

 

Changes made on the code:

Exclude Locked layers and/or xref,

Pline with to Extend/Trimmed according to current dimscale.

 

*Note: Currently the code is designed for 12" , i can however tweak it to work for both 12" and 18", but i need a basis as to when the block is 12" or 18". or are they both present on a drawing at one time?

a quick workaround is a list of blocks as reference.*

Posted
Now that you mentioned it. I'm not so sure :lol:,

it gives you a point list if the blocks are the same, weird really...

Strange, I've just tested it here at the office on Vanilla 2012 ... the vlax-invoke gives an error. If I use vla-IntersectWith then it doesn't error, but the safearray returned is empty:
Command: (setq bo (vlax-ename->vla-object (car (entsel))))
Select object: #<VLA-OBJECT IAcadBlockReference2 000000002b71bc68>
Command: (setq po (vlax-ename->vla-object (car (entsel))))
Select object: #<VLA-OBJECT IAcadLWPolyline2 000000002ba07218>
Command: (setq IntPts (vla-IntersectWith po bo acExtendThisEntity))
#<variant 8197 ...>
Command: (setq IntPts (vlax-variant-value IntPts))
#<safearray...>
Command: (vlax-safearray-get-l-bound IntPts 1)
0
Command: (vlax-safearray-get-u-bound IntPts 1)
-1
Command: (vlax-safearray->list IntPts)
; error: ActiveX Server returned an error: Invalid index

So I guess you either need to know the "size" and "shape" of each block beforehand or use the ShrinkWrap to calculate the boundary of the block. That way any block would work, since you can then use the IntersectWith to get all intersect points. E.g.:

Command: (setq bo (vlax-ename->vla-object (car (entsel))))
Select object: #<VLA-OBJECT IAcadLWPolyline2 0000000058424628>
Command: (setq IntPts (vla-IntersectWith po bo acExtendThisEntity))
#<variant 8197 ...>
Command: (setq IntPts (vlax-variant-value IntPts))
#<safearray...>
Command: (vlax-safearray-get-u-bound IntPts 1)
5
Command: (setq IntVals (vlax-safearray->list IntPts))
(-57938.6 -15386.3 0.0 -57025.8 -15298.7 0.0)
Command: (setq IntPts nil)
nil
Command: (while IntVals (setq IntPts (cons (list (car IntVals) (cadr IntVals) (caddr IntVals)) IntPts) IntVals (cdddr IntVals)))
nil
Command: !IntPts
((-57025.8 -15298.7 0.0) (-57938.6 -15386.3 0.0))

From there it's quite easy to figure out which of those points are closest to the pipe's midpoint, and then use that as the pipe's new endpoint (no need to figure out by how much to lengthen/shorten the pipe).

Posted
.....From there it's quite easy to figure out which of those points are closest to the pipe's midpoint, and then use that as the pipe's new endpoint (no need to figure out by how much to lengthen/shorten the pipe).

 

Nice :thumbsup:

 

Only thing though, for every pipe you need to re-itereate thru ALL the blocks, AND with the supplied argument of acExtendThisEntity will inadvertently gives you more than just a couple of values to test for distance closest to the pipe's midpoint.

Thats the reason why I asked for opinions and guidance regarding this, Would that take longer to process than the former (lengthen/shorten the pipe)? and will that be more efficient?

 

Any thoughts?

 

Cheers

 

FWIW, i like the snippets Irné , Clever :)

Posted

Yep, very inefficient and may produce erroneous "intersections" if the pipe has a bend in it somewhere. Perhaps a better idea is to first get the closest block to the endpoint of the polyline, something like this:

;;; Obtain Block closest to point
;;; Arguments:
;;; blklst - List of block reference objects
;;; pt     - Point list
(defun ClosestBlock (blklst pt / dist)
 (setq dist (distance pt (vlax-get (car blklst) 'InsertionPoint)))
 (last (vl-remove-if-not
         '(lambda (blk / d)
            (if (<= (setq d (distance pt (vlax-get blk 'InsertionPoint))) dist)
              (setq dist d)))
         blklst)))

Then change the pipe such that it's endpoint is on the block's insertion point. Then get the boundary of only that block and make a temporary polyline of it. Then get the intersections using the acExtendNone option on the temporary polyline and the pipe, erase the temporary PL and get the closest intersection to the midpoint of the pipe's segment (since the pipe may have a bend in it), then change the pipe's endpoint to that.

Posted (edited)
Yep, very inefficient and may produce erroneous "intersections" if the pipe has a bend in it somewhere. Perhaps a better idea is to first get the closest block to the endpoint of the polyline......

 

Then change the pipe such that it's endpoint is on the block's insertion point. Then get the boundary of only that block and make a temporary polyline of it. Then get the intersections using the acExtendNone option on the temporary polyline and the pipe, erase the temporary PL and get the closest intersection to the midpoint of the pipe's segment (since the pipe may have a bend in it), then change the pipe's endpoint to that.

 

Okay then, I will try to write another code using that approach..

Meanwhille i attached drawing file where i tests the previous code.

 

The sample2.dwg

Edited by pBe
Posted

Actually, trying to figure this out. You don't need the "boundary shrink wrap" at all:

;;; Convert an ActiveX point list to an AutoLisp points list
;;; Arguments:
;;; lst - The points list, e.g. (x1 y1 z1 x2 y2 z2 ... xN yN zN)
;;; 3d  - nil = 2D; otherwise = 3D
(defun ActiveXPoints->AutoLispPoints  (lst 3d / res)
 (if (= (type lst) 'Variant)
   (setq lst (vlax-variant-value lst)))
 (if (= (type lst) 'SafeArray)
   (setq lst (vl-catch-all-apply 'vlax-safearray->list (list lst))))
 (if (= (type lst) 'List)
   (progn (if 3d
            (while lst
              (setq res (cons (list (car lst) (cadr lst) (caddr lst)) res)
                    lst (cdddr lst)))
            (while lst
              (setq res (cons (list (car lst) (cadr lst)) res)
                    lst (cddr lst))))
          (reverse res))))

;;; Get the intersection points between a block and another object
;;; Arguments:
;;; blk - The block Reference object
;;; obj - The other object
(defun BlockIntersections (blk obj / tmp lst)
 (setq lasten (entlast))
 (setq tmp (vla-Explode blk))
 (if (= (type tmp) 'Variant)
   (setq tmp (vlax-variant-value tmp)))
 (if (= (type tmp) 'SafeArray)
   (setq tmp (vl-catch-all-apply 'vlax-safearray->list (list tmp))))
 (if (= (type tmp) 'List)
   (foreach eo tmp
     (if (not (wcmatch (vla-get-ObjectName eo) "AcDbAttributeDefinition"))
       (setq lst (append lst (ActiveXPoints->AutoLispPoints (vla-IntersectWith eo obj acExtendNone) t))))
     (vla-Delete eo)))
 lst)

It's basically just exploding the block temporarily, then getting all the intersections from those entities while deleting them. Then you get the closest matching intersection point.

Posted (edited)

I have attached a sample drawing with a few of the sprinkler heads we use and the piping and some layers we use.

 

Drawing1.dwg

 

Not sure if it helps, but all heads are on the same layer SPRNKS, other blocks that get scaled are on various layers but just need all blocks in model space scaled, plines for pretty pipe to scale are always on SPRKVIEW but might be different colors or linetypes, and in the drawing you can see that all but one head is 12" diameter. The odd shaped head on the bottom of the drawing is 18" diameter. These are the sizes when the block has a scale of 1, which is 1/8" scale in the drawing.

 

From what I can tell and understand, it doesn't matter the size of the block because the pretty pipe is already cut to where it needs when you create it originally with HydraCAD's program. The pretty pipe plines will be shortened or lengthened the exact same.

 

pBe: I tried your updated code but it wouldn't go ahead and run through it, no error or anything though... I will play around with it a little bit. In the mean time, hopefully the attached drawing gives you a better idea of what I am working with. It is setup for 1/8" scale right now. When you open it you can see what the dimscale is and the block scale for 1/8" setup.

 

***EDIT****

Oh, and also you will notice that although they are plines, muliple plines together, like at a bend, are not connected together. That is just how the HydraCAD program creates the pretty pipe, so irneb you don't have to get the center of the entire polyline with bends like you mentioned, just the center point of each individual pline. :)

Edited by brawleyman
Posted

 

[Not sure if it helps, but all heads are on the same layer SPRNKS, other blocks that get scaled are on various layers but just need all blocks in model space scaled, plines for pretty pipe to scale are always on SPRKVIEW but might be different colors or linetypes, and in the drawing you can see that all but one head is 12" diameter. The odd shaped head on the bottom of the drawing is 18" diameter. These are the sizes when the block has a scale of 1, which is 1/8" scale in the drawing.

 

 

It does help , :)

 

pBe: I tried your updated code but it wouldn't go ahead and run through it, no error or anything though... I will play around with it a little bit. In the mean time, hopefully the attached drawing gives you a better idea of what I am working with. It is setup for 1/8" scale right now. When you open it you can see what the dimscale is and the block scale for 1/8" setup.

 

 

I wasnt aware you want to be prompted for scale value, all this time i thought you want it to work "automagically", so what the code does when you run it, will detect the current dimscale value, comapre it o the approved scales table and make the necessary changes.

 

on the sample drawing i posted, what you'll do is change the value of dimscale, the run MIT, or you can create dimstyles with the values you need , make one of them current then run MIT. Would you rather be prompted for scale?

 

Now that i have an actual drwing to work on, maybe i can set the code to work under these conditions and make the necesary adjustments. For now try on the sample drawing i posted while i'm tinkering with code to work on your sample.

Posted
It does help , :)

 

 

 

I wasnt aware you want to be prompted for scale value, all this time i thought you want it to work "automagically", so what the code does when you run it, will detect the current dimscale value, comapre it o the approved scales table and make the necessary changes.

 

on the sample drawing i posted, what you'll do is change the value of dimscale, the run MIT, or you can create dimstyles with the values you need , make one of them current then run MIT. Would you rather be prompted for scale?

 

Now that i have an actual drwing to work on, maybe i can set the code to work under these conditions and make the necesary adjustments. For now try on the sample drawing i posted while i'm tinkering with code to work on your sample.

 

No, I don't want to be prompted for the scale value in this new routine you are working on because I already have a routine with a window and pull down where I can choose the scale I want the drawing to be that sets the dimscale, lts, and filletrad. What I am wanting is a routine that will run right after that will read the new dimscale I just set and scale everything for me automatically. Also, it was just the one scale that wasn't working for some reason, I tried a couple others and they worked. I don't need the "approvedscales" in this routine because it is already established in my drawing scale routine.

 

What I am after is extremely basic. Scale ALL blocks in model space while bypassing anything on a locked layer. Scale all pretty pipe from its midpoint, then shorten/lenghten all ends to match the new sized blocks/original end of lines. The drawing I attached earlier has pretty much everything you will encounter when drawing pipe (except pipe at various angles other than 90) which includes pretty pipe between heads, bends, "t" connections, etc.

 

The very first code you posted up earlier seemed to actually be the closest to what I am wanting, except for the additional scales working properly for scaling the pipe and selecting every block in model space to scale, except x-ref's.

Posted

I forgot that I already had this piece of code from before that I was using to scale all of the blocks, which works perfect for scaling all blocks, and it doesn't have to bypass locked layers or anything.

 

          (princ "\nPlease wait while all blocks are scaled to ")(princ thehfscale)(princ)

         (SETQ SSb (ssget "_X" (list (cons 0 "INSERT")(cons 410 (getvar "ctab"))) ) INDEX 0 TOT 0)
         (REPEAT (SSLENGTH SSb)
           (SETQ ENT (ENTGET (SSNAME SSb INDEX)))
           (SETQ ENT (SUBST (CONS 41 (getvar "dimscale"))(ASSOC 41 ENT) ENT))
           (SETQ ENT (SUBST (CONS 42 (getvar "dimscale"))(ASSOC 42 ENT) ENT))
           (SETQ ENT (SUBST (CONS 43 (getvar "dimscale"))(ASSOC 43 ENT) ENT))
           (ENTMOD ENT)
           (SETQ TOT (+ 1 TOT))
           (SETQ INDEX (+ 1 INDEX))
         );end repeat

 

So actually, all I really need is a way to scale just the pretty pipe from their midpoints and shorten/lengthen it to match the new size of the blocks.

Posted

Just a question: How is the routine to know by how much the pipe needs to be scaled? I.e. will you always use the routine from 1/8" scale and never use it to adjust from say 3/32" back to 1/8"?

 

One way would be to use the current block's scale factor and then calculate the variation to the current dimscale. But that would mean you need to run both codes simultaneously, or at least obtain this difference before scaling the blocks.

 

Also, why scale the pipe from its midpoint? Why not simply change its width? If you scale it and the pipe has a bend in it somewhere that bend might move and throw out your entire layout.

Posted

.....because I already have a routine with a window and pull down

.....I don't need the "approvedscales" in this routine because it is already established in my drawing scale routine.

....I forgot that I already had this piece of code from before that I was using to scale all of the blocks, which works perfect for scaling all blocks, and it doesn't have to bypass locked layers or anything.

 

So actually, all I really need is a way to scale just the pretty pipe from their midpoints and shorten/lengthen

it to match the new size of the blocks....

 

Well.... as for me... ->>> [Polyline scale from midpoint]

 

 
(defun MidOfPoly  (ent)
     (vlax-curve-getPointAtParam
           ent
           (/ (- (vlax-curve-getEndParam ent)
                 (vlax-curve-getStartParam ent))
              2)))

 
(repeat ...
     (command "_scale" ent "" (MidOfPoly ent) scale )
     .....
 )

 

.... [b]The rest of your codes...[/b] 

 

Moving along now... :glare:

Posted

This is almost what I need. http://www.cadtutor.net/forum/showthread.php?20350-lengthen-delta-multiple&

 

I just need to change it so that it will automatically select all plines on the SPRKVIEW layer (I already changed that part) then automatically choose "both" (which I could eventually strip the code so that it does it automatically for me without the prompt). The last bit I need is just to figure out how to scale every pline from it's midpoint, then integrate this routine I found to shorten/lengthen the lines based on the dimscale.

 

I am getting there once piece at a time.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...