Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

converting special layer with special line weight to special layer name ??

10 REPLIES 10
Reply
Message 1 of 11
ahmad4343
499 Views, 10 Replies

converting special layer with special line weight to special layer name ??

Hi , i have line in the drawing that exists on layer A-Wall it has different lineweight 0.05 from true wall. 

Now usually my routing : i select this line and then select similar to convert it to layer glazing.

i need lisp that by one command convert the objects on layer A-wall with layer 0.05 only to glazing.

 

 

10 REPLIES 10
Message 2 of 11
BlackBox_
in reply to: ahmad4343

Code assumes the A-WALL layer is unlocked:

 

(vl-load-com)

(defun c:FOO (/ *error* layerName acDoc)

  (defun *error* (msg)
    (if acDoc
      (vla-endundomark acDoc)
    )
    (cond ((not msg))                                                   ; Normal exit
          ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
          ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
    )
    (princ)
  )

  (if (tblsearch "layer" (setq layerName "glazing"))
    (if (ssget "_x" '((8 . "A-WALL") (370 . 5)))
      (progn
        (vla-startundomark
          (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
        )
        (vlax-for x (vla-get-activeselectionset acDoc)
          (vl-catch-all-apply 'vla-put-layer (list x layerName))
        )
      )
      (prompt "\n** Nothing selected ** ")
    )
    (prompt (strcat "\n** Layer \"" layerName "\" not found ** "))
  )
  (*error* nil)
)

 



"How we think determines what we do, and what we do determines what we get."

Message 3 of 11
Kent1Cooper
in reply to: ahmad4343


@ahmad4343 wrote:

Hi , i have line in the drawing that exists on layer A-Wall it has different lineweight 0.05 from true wall. 

Now usually my routing : i select this line and then select similar to convert it to layer glazing.

i need lisp that by one command convert the objects on layer A-wall with layer 0.05 only to glazing.


I discovered by accident one time a very interesting curiosity, which you may not want to take advantage of for reasons described below, but just in case:

 

If you use (subst) & (entmod) to replace the Layer name in an object's entity data, it is not necessary for the new Layer to be in the drawing already -- if it isn't, it will be created in the process [with default color 7, continuous linetype, etc.] -- and therefore it is not necessary to check whether it exists before assigning it to objects!  So you can, if you like, do something like this:

 

(if (setq ss (ssget "_X" '((8 . "A-WALL") (370 . 5)))
  (repeat (sslength ss)

    (setq edata (entget (ssname ss 0)))

    (entmod (subst '(8 . "glazing") (assoc 8 edata) edata))

    (ssdel (ssname ss 0) ss)

  ); repeat

); if

 

No check on whether the Layer exists, nor notification to the User [or making of it] if it doesn't, because it will as soon as it's been assigned to the first object in the selection.  [Neither CHPROP nor CHANGE nor VLA methods will do that -- they're pickier, and require the Layer to exist already.]  However, if it may turn out that way, but you want a non-default color or linetype or other properties assigned to that Layer, you'd probably want to make it first anyway.

Kent Cooper, AIA
Message 4 of 11
BlackBox_
in reply to: Kent1Cooper

I'm sure it was a simple mistake, but for others... Be mindful of:

 

; error: malformed list on input
_$ 

 


@Kent1Cooper wrote:
No check on whether the Layer exists, nor notification to the User [or making of it] if it doesn't, because it will as soon as it's been assigned to the first object in the selection.  [Neither CHPROP nor CHANGE nor VLA methods will do that -- they're pickier, and require the Layer to exist already.However, if it may turn out that way, but you want a non-default color or linetype or other properties assigned to that Layer, you'd probably want to make it first anyway.

Actually Kent, and I should have included this in my earlier offering (I'd update my post, but these forums don't support this common functionality; grrr), but as it happens the vla-Add Method returns the newly created layer, or the existing layer without error.

 

For completeness... Since I'm taking the time to add that littl e ditty, I also took the time to account for A-WALL being locked, all of which support a simple Ctrl+Z / UNDO (another reason I prefer entity modification, let alone Table modification [in this case the LayerTable], to be done via Visual LISP is for the expedient UNDO functionality😞

 

(vl-load-com)

(defun c:FOO (/ *error* layerName acDoc oLayers oLayer lock)

  (defun *error* (msg)
    (if lock
      (vla-put-lock oLayer :vlax-true)
    )
    (if acDoc
      (vla-endundomark acDoc)
    )
    (cond ((not msg))                                                   ; Normal exit
          ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
          ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
    )
    (princ)
  )

  (if (ssget "_x" (list (cons 8 (setq layerName "A-WALL")) '(370 . 5)))
    (progn
      (vla-startundomark
        (setq acDoc (vla-get-activedocument (vlax-get-acad-object)))
      )
      (if (setq lock
                 (= :vlax-true
                    (vla-get-lock
                      (setq oLayer
                             (vla-item (setq oLayers (vla-get-layers acDoc))
                                       layerName
                             )
                      )
                    )
                 )
          )
        (vla-put-lock oLayer :vlax-false)
      )
      (vla-add oLayers (setq layerName "glazing"))
      (vlax-for x (vla-get-activeselectionset acDoc)
        (vla-put-layer x layerName)
      )
    )
    (prompt "\n** Nothing selected ** ")
  )
  (*error* nil)
)

 

Cheers

 

 

 

 

 



"How we think determines what we do, and what we do determines what we get."

Message 5 of 11
BlackBox_
in reply to: Kent1Cooper


@Kent1Cooper wrote:

(if (setq ss (ssget "_X" '((8 . "A-WALL") (370 . 5)))

  (repeat (sslength ss)

    (setq edata (entget (ssname ss 0)))

    (entmod (subst '(8 . "glazing") (assoc 8 edata) edata))

    (ssdel (ssname ss 0) ss)

  ); repeat

); if

 


Also, FWIW - Tabling the discussion of 'but it works'... I'll see if I cannot find where I learned this from others more knowledgeable than I, but (if memory serves), it is not recommended to remove entity pointers from a selection set actively being iterated.

 

I know, I know... Code similar to your above has worked for years, but just sharing what I've learned... And that is, that it is better to increment/decriment an index used to obtain the entity pointer:

 

(if (setq ss (ssget "_x" '((8 . "A-WALL") (370 . 5))))
  (repeat (setq i (sslength ss))
    (entmod
      (subst '(8 . "glazing")
             (assoc 8 (setq edata (entget (ssname ss (setq i (1- i))))))
             edata
      )
    )
  )
)

 

... This may also be a good time to point out that ENTMOD, while great for its inherent ability to add new layers on the fly, it does not however account for the source entity being on a locked layer (not sure if you already pointed that out or not).

 

Cheers



"How we think determines what we do, and what we do determines what we get."

Message 6 of 11
shehab10
in reply to: ahmad4343

I got this message although i have the same letter case.

** Nothing selected **

the lineweight of desired A-WALL is 0.05

Message 7 of 11
BlackBox_
in reply to: shehab10

You've assigned a lineweight of 0.05 to the Layer "A-WALL" (so all entity lineweights are set to ByLayer)... Or... You have Line entities on the layer "A-WALL" that have been set to a lineweight of 0.05 individually (like the OP of this thread describes)?

 

The code posted above does not account for the former, and is quite successful at the latter.

 

Hope this makes (more?) sense to you.

 

Cheers



"How we think determines what we do, and what we do determines what we get."

Message 8 of 11
shehab10
in reply to: BlackBox_

Well, the code it does not work right now by layer.

what if i want also by specific line weight like 0.35

 

 

 

Message 9 of 11
BlackBox_
in reply to: shehab10

You're missing the point, methinks... If all entities on a given layer are set to ByLayer, and the layer itself is determining the lineweight (which is very common practice), then there's no need to filter a selection set for entity-specific lineweights, as is what the OP requested and the code above does (which is why it doesn't work for you - you're attempting something different).

 

The logic for determining which entities to move is different.

 

That said, you'd need to select all entities on the target layer that are set to ByLayer (i.e., have no DXF 370 grouped pair [... (370 . "~*#*")...?])... And to your latest deviation (changing which lineweight[s] to identity, and move), you'd have to instead first prompt for a real stored to variable to identify the lineweight value, and then apply that to your selection set filter conditionally, wrapping all of that into an AND statement.

 

HTH



"How we think determines what we do, and what we do determines what we get."

Message 10 of 11
Lee_Mac
in reply to: BlackBox_


@BlackBox_ wrote:

That said, you'd need to select all entities on the target layer that are set to ByLayer (i.e., have no DXF 370 grouped pair [... (370 . "~*#*")...?])...


FYI: wildcard patterns can only be used with string groups; for integer/real valued groups you can use either logical or relational operators. However, for this case you can use simply:

 

(ssget "_X" '((370 . -1)))

Since ssget will still filter for DXF groups which are not present in the entget output for an entity.

 

Message 11 of 11
BlackBox_
in reply to: Lee_Mac


@Lee_Mac wrote:

@BlackBox_ wrote:

That said, you'd need to select all entities on the target layer that are set to ByLayer (i.e., have no DXF 370 grouped pair [... (370 . "~*#*")...?])...


FYI: wildcard patterns can only be used with string groups; for integer/real valued groups you can use either logical or relational operators. However, for this case you can use simply:

 

(ssget "_X" '((370 . -1)))

Since ssget will still filter for DXF groups which are not present in the entget output for an entity.

 


Thanks for clarifying, my friend... My first thought was to include logical operators, and opted for what I had hoped would work "~" as shorthand given I was typing from my iPhone.

 

I prefer to use the logical operators personally, given their carry over into .NET API as Kean shows here.

 

Cheers



"How we think determines what we do, and what we do determines what we get."

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost