Jump to content
pBe

Annotative troubles

Recommended Posts

pBe

To All.. please help :)

 

what i'm trying to do is update the annotative state ot a TEXT/MTEXT with mulitple Anno scale i was able to drill down up to the point "ACDB_ANNOTATIONSCALES" which shows me the number of annotative scale the entity have

.... testing it .. then deal with it .. after that i'm stumped.. cant seem to update the entity to loose the other

annotative scales, say i the text has 4 annotative scale.. i'll take out 3 then update the text.. but nada

heres what i have so far...

 

(defun c:kj ()(vl-load-com)
      (setq disdg (vla-get-activedocument (vlax-get-acad-object))
            dd_utl (vla-get-utility disdg))
       (vla-getentity dd_utl 'obg 'pwnt "\nSelect object: ")
       (setq str_scl (vla-GetExtensionDictionary obg)
        frst (vla-item str_scl 0))

 (gt_scl frst)
     )
(defun gt_scl (frst)
(setq scl_lst (vla-item frst 0) prcd2 0)
 (repeat (vla-get-count scl_lst)
   
   (setq dlkd (vla-item str_scl prcd2))
   
    (setq i2nyun (entget (vlax-vla-object->ename (vla-item dlkd 0)))
    txt_scle (assoc 40 i2nyun))
    
   (if (/= txt_scle ******) ; the condition is met
      (vla-delete dlkd))
   )
)

;;;; or this method

 

 

(defun gt_scl (frst) 
(setq scl_lst (vla-item frst 0));(vla-addxrecord scl_lst "New_SCale_list")
 (vlax-for vegeta scl_lst
    (setq i2nyun (entget (vlax-vla-object->ename vegeta))
    txt_scle (assoc 40 i2nyun))
   (if (/= txt_scle ******) ; the condition is met
      (vla-delete dlkd))
   
   )
 )

 

or am i better off not using enames? and stick with vla-objects?

 

vla-update? vla-replace? i think i hit a stonewall

which brings me to another question..

 

vlax-item gave me this : IAcadDictionary: A container object for storing and retrieving objects

vlax-for gave me this : IAcadObject: The standard interface for a basic AutoCAD object

 

whats the main difference?

Edited by Tiger
added codetags

Share this post


Link to post
Share on other sites
BlackBox

Congrats on your first post, and welcome to the forums!

 

I *think* you're looking for this, to apply the desired annotation scale:

 

(setvar 'cannoscale (strcat "1\" = [color=red][i]<Desired_AnnoScale>[/i][/color]'"))

 

 

Or, perhaps this may be of use:

 

(setvar 'cannoscale (strcat "1\" = " (rtos (getvar 'dimscale) 2 0) "'"))

 

 

Please note the space " " before and after the equal sign "="... this is present for my annotative scales list, yours may not include the spaces, and should be removed if that is the case. The text string should exactly match your format.

 

...

vlax-item gave me this : IAcadDictionary: A container object for storing and retrieving objects

vlax-for gave me this : IAcadObject: The standard interface for a basic AutoCAD object

 

whats the main difference?

 

The vla-item function returns a vla-object in many cases from a collection, example:

 

(setq layerItem (vla-item (vlax-get-layers *activeDoc*) "[i][color=red]<LayerName>[/color][/i]"))

 

 

The vlax-for function is used to do, check, of modify something for each vla-item in a vla-collection object, example:

 

(vlax-for lay (vla-get-layers *activeDoc*)
 (vla-put-freeze lay :vlax-true))

 

 

Hope this helps!

Share this post


Link to post
Share on other sites
pBe

Thx RenderMan... nice to be seen :)

 

Anyway.. you gave me an idea as to where i can compare the list i got as to the current anoscale... but what i'm looking for is getting rid of "annoscale" on the entity itself... not all but leave 1... hmmmn like this, select a MTEXT by grips.. and you will see shadows of the different annoscales it has ... now the goal is slecting this text (entitities), detect all the anoscale scales, leave the ones i dictated, and update...

 

i got to the point where i extracted the number of annoscales it has. but my problem is updating or making the others dissapear...

 

ordinarily you select the text.. go to properties... go to annotative scale box.. select the scales you want to get rid of..

 

remember, what i want is to to update the enitities one by one...

 

thanks sire.....

Share this post


Link to post
Share on other sites
BlackBox

Sadly, *to the best of my knowledge* this can only be done (programmatically) via DXF XData.

Share this post


Link to post
Share on other sites
pBe

no worries,,, someday i'll figure it out.... but hey great advice on cannoscale variable :D

 

BTW i posted the same thread at AUGI forum... apologies.... 8)

Share this post


Link to post
Share on other sites
alanjt

To turn off display of additional, inactive scales, look at the system variable "SELECTIONANNODISPLAY".

 

You can also remove additional scales from the Annotative Scales option upon a right-click on the object; or were you wanting to remove additional scales in code?

Share this post


Link to post
Share on other sites
pBe

thanks buddy...

 

The thing is, its not the display that bothers me. its the thought of that entity does have annoscales other than the scale it was intended for... taking it out using right click works well but if you have to check hundreds of dwgs to go through... welll you know what i mean.... 8)

 

i intend to use the selection sets after i figure out how to do it with just one entity.. but i will use it to find all entities with annoscales.. detect the active ones the annihilate the rest ..:D my problem is after getting what i need from the selected object i dont know how to update it.. similar to entupd/entmod method but in VLISP... i'm totally bummed out on that part.. dont know when and how to used vla-replace/vla-update/xdata stuff

 

thanks for the advice though, honestly i didnt know about variable for the anno display.. cool..... and yup i want to remove it by code....

 

:wink:

 

besides files with too many annoscales are rather large...

Share this post


Link to post
Share on other sites
irneb

Well, a "quick-fix" solution would be to use the ObjectScale command's command-line arguments.

(defun c:ObjectScaleCurOnly (/ ss n scLst OSC:GetScales)
 (print "Select the objects you wish to modify: ")
 (if (or (setq ss (ssget "I")) (setq ss (ssget)))
   (progn
     ;; Define helper function to get scales attached to an entity
     (defun OSC:GetScales (en / ed xn xd cdn cdd asn asd cn cd sn sd cannoscale)
       (setq ed (entget en))
       (if (and
             ;; Get the XDictionary attached to the object
             (setq xn (vl-position '(102 . "{ACAD_XDICTIONARY") ed))
             (setq xn (cdr (nth (1+ xn) ed)))
             (setq xd (entget xn))
             ;; Get the Context Data Management dictionary attached to the XDictionary
             (setq cdn (vl-position '(3 . "AcDbContextDataManager") xd))
             (setq cdn (cdr (nth (1+ cdn) xd)))
             (setq cdd (entget cdn))
             ;; Get the Annotation Scales dictionary attached to the CD
             (setq asn (vl-position '(3 . "ACDB_ANNOTATIONSCALES") cdd))
             (setq asn (cdr (nth (1+ asn) cdd)))
             (setq asd (entget asn))
             ;; Get the 1st scale attached
             (setq cn (assoc 3 asd))
             (setq cn (member cn asd))
           )
         ;; Step through all scales attached
         (while cn
           (if (and (= (caar cn) 350) ;It it's pointing to a scale record
                    ;; Get the record's data
                    (setq cd (entget (cdar cn)))
                    ;; Get the Context data class
                    (setq sn (assoc 340 cd))
                    (setq sd (entget (cdr sn)))
                    (setq sn (assoc 300 sd))
                    ;; Check if the scale is already in the list
                    (not (vl-position (cdr sn) scLst))
               )
             ;; Add it to the list
             (setq scLst (cons (cdr sn) scLst))
           )
           (setq cn (cdr cn))
         )
       )
     )

     ;; Find a list of scales used in selection
     (setq n (sslength ss))
     (while (>= (setq n (1- n)) 0)
       (OSC:GetScales (ssname ss n))
     )

     ;; Add the current scale to the selection
     (setq cannoscale (getvar "CANNOSCALE"))
     (command "._ObjectScale" ss "" "_Add" cannoscale "")

     ;; Remove all other scales attached
     (command "._ObjectScale" ss "" "_Delete")
     (foreach n scLst
       (if (wcmatch (strcase n) (strcat "~" (strcase cannoscale)))
         (command n)
       )
     )
     (command "")
   )
 )

 (princ)
)

The problem with anno scales are that they are nested 5 levels deep into the dictionaries attached to the entity.

Share this post


Link to post
Share on other sites
pBe

works great :shock:

 

delete all then put the current back... splendid idea... thanks a mil.. i keep you posted how it goes...

 

in vlisp i was able to retrieve the scales but after that i dont what to do...

while you're at it.. can you tell me how and when to use (vla-replace...) and

(vla-update ....)?

 

Again thanks irneb....:)

Share this post


Link to post
Share on other sites
irneb

Just to be clear: it's first add the current, then delete all but the current. The problem with doing it the other way, is you will usually end up with 2 scales (the last in the list for that object) and the current - since you cannot remove all the scales from an object (it has to have at least one). So if you're going the VLA / entmod route, please remember this.

 

I had something which removed scales from the entire DWG without checking such stuff. Causes huge problems as drawings start crashing.

Share this post


Link to post
Share on other sites
pBe
Just to be clear: it's first add the current, then delete all but the current. The problem with doing it the other way, is you will usually end up with 2 scales (the last in the list for that object) and the current - since you cannot remove all the scales from an object (it has to have at least one). So if you're going the VLA / entmod route, please remember this.

 

I had something which removed scales from the entire DWG without checking such stuff. Causes huge problems as drawings start crashing.

 

You're absolutely right about the sequence :) i'll keep it mind

 

Thank you so much

Share this post


Link to post
Share on other sites
pBe

here is the not so final program :unsure:

 

it bombed when it encountered a dynamic block with an Anonymouse name.. oh well

 

other than that its cool...

Thank you irneb/renderman/alanjt

 

(defun c:RemoveAnnoscale (/ disdg dd_ss)(vl-load-com)
      (setq disdg (vla-get-activedocument (vlax-get-acad-object))
      dd_ss (vla-get-selectionsets disdg) exs:set nil)
  (vla-setvariable disdg "cmdecho" 0)
(vlax-for item dd_ss (if (= (vla-get-name item) "AnoSet") (setq exs:set T))
  )
(if exs:set (vla-delete (vla-item dd_ss "AnoSet"))
  )
(setq dd_sset (vla-add dd_ss "AnoSet") nmtr 0 )
(vla-selectonscreen dd_sset )
   (repeat (vla-get-count dd_sset)
   (setq obg (vla-item dd_sset nmtr) str_scl (vla-GetExtensionDictionary obg))
         (if (> (vla-get-count str_scl) 0)
      (progn (setq  frst (vla-item str_scl 0))
      (vl-cmdf "._ObjectScale" (vlax-vla-object->ename obg) "" "Add" (getvar "CANNOSCALE") "")
      (gt_scl frst))
     )
   (setq nmtr (1+ nmtr))
 )
   )
(defun gt_scl (frst / i2nyun tr1) 
(setq scl_lst (vla-item frst 0) scl_lstt nil)
  (if (> (vla-get-count scl_lst) 1)(progn
 (vlax-for vegeta scl_lst  
    (setq i2nyun (entget (vlax-vla-object->ename vegeta)))
    (setq tr1 (entget (cdr (assoc 340 i2nyun))))
   (setq scl_lstt (cons (cdr (assoc 300 tr1)) scl_lstt ))
 )
  (vl-cmdf "._ObjectScale" (vlax-vla-object->ename obg) "" "delete")
 (foreach sc_nm scl_lstt
        (if (/=  sc_nm (getvar "CANNOSCALE"))
        (vl-cmdf sc_nm))
   )(vl-cmdf "")    

    )
   ) 
  )


 

i use the sequence from irneb.. thnaks buddy 8)

i totally gave up on VLA DXF extraction and update

Share this post


Link to post
Share on other sites
irneb

I'm trying to really get hold of a way to edit object's scales and / or Delete scales from the DWG programmatically. The command-line version is just too slow!

 

I had something like this previously, but as mentioned caused crashes because deleting the scale (if it's already assigned) would cause errors in the DWG. See this thread on AUGI: http://forums.augi.com/showthread.php?t=74324

 

However, I've since tried another route - to first get hold of a list of used scales - thus only searching the DWG once (not each time a scale is deleted as the -ScaleListEdit command does). This should make the "Purging" of scales a lot faster. It's just that I'd actually like to extend the Purge into a "merge".

 

E.g. if there's a scale such as 1:50_XREF in the drawing as well as a 1:50, I'd like to modify each entity assigned to 1:50_XREF so it's now assigned to 1:50 instead. The attached is as far as I've gotten, the xlaxx is just some utility functions I use to make vla a bit "easier" and more efficient. The AnnoScales:RemoveScales defun seems to run fine, but it doesn't do anything to the objects.

 

The end of my lisp should rename the XREF (and the _1_2.... scales) to what they should have been to begin with. But if that scale already exists it needs to check if the *_XREF* scale's been used by something, if not it can simply be deleted. If it has been used I need to modify the entities assigned to the "wrong" scales to the correct one before deleting them. And I'm trying to keep clear of using the command-line (due to speed issues), but it seems I'll have to go that route :unsure:. Anyone have experience of this, or some suggestions? I'm banging my head against a rock it seems.

vlaxx.lsp

AnnoScales.LSP

Share this post


Link to post
Share on other sites
pBe

And I'm trying to keep clear of using the command-line (due to speed issues),

 

So.. were you able to find a way around this Irneb? :unsure:

Share this post


Link to post
Share on other sites
irneb

Nope, I have to use the ObjectScale command. There's no way through either DXF / VLA to remove scales from entities. That's fine for a handful of entities, but what about 1000's? I'm starting to think this is a job for DotNet.

Share this post


Link to post
Share on other sites
Sbeth85

IrneB-

I'm new to LISPS, I copied and pasted this code into a txt document, tried to APPLOAD it, but my computer didn't "see" it in my folder.

Could you tell me how to actually implement this code in AutoCad?

thanks!

Share this post


Link to post
Share on other sites
irneb
IrneB-

I'm new to LISPS, I copied and pasted this code into a txt document, tried to APPLOAD it, but my computer didn't "see" it in my folder.

Could you tell me how to actually implement this code in AutoCad?

thanks!

Did you use Notepad? Be carful, Notepad adds a .txt extension to the file you save by default. When saving you need to choose All Files (*.*) in the save dialog and then type out the full name, else you end up with a file called MyFile.lsp.txt and acad's appload won't see it.

 

This is one of the major reasons Notepad is a bit of a problem. When working with acad, I tend to prefer using its built-in VLIDE command - it's much better suited to Lisp (you can even directly load the lisp from there with one click). Not to mention it provides good methods to check exactly what's going on as the lisp runs (item for item). To see a few good tuts on it Lee Mac's site provides good descriptions: http://www.lee-mac.com/tutorials.html#vlide

 

If you're unable to use VLIDE (e.g. you're actually in BricsCAD) you could use Notepad++ instead. Search for it on the web, it's a free replacement for Notepad with lots of programmer help tools.

Share this post


Link to post
Share on other sites
Sbeth85

Irneb-

You did it!! Thank you :)

I'd tried putting it into Notepad, then saving, then trying to Rename the file, and it didn't work.

Saving as "All files" and including the .lsp in the title did the trick!

 

I was curious about VLIDE, I opened it and pasted in the code, but then nothing seemed to happen.

But I'm satisfied with this Notepad method. Thank you again!

Share this post


Link to post
Share on other sites
Sbeth85

Here's a follow-up:

Do I need to AppLOAD this LISP each time? Or can I already assign an Alias for it and use it whenever I log in?

Share this post


Link to post
Share on other sites
irneb

You're welcome!

I'd tried putting it into Notepad, then saving, then trying to Rename the file, and it didn't work.
This is actually due to a setting in Windows (hiding default extensions). To turn this off, open Control Panel, then the Folder Options item. Under its View tab scroll down to "Hide extensions for known file types" and turn that option off (un-check). It should now show the txt extensions as well and allow you to rename them properly.

 

Here's a follow-up:

Do I need to AppLOAD this LISP each time? Or can I already assign an Alias for it and use it whenever I log in?

There are various ways you can get this to load automatically. Again, many ways shown on Lee Mac's site: http://lee-mac.com/autoloading.html

 

I prefer using a MNL file together with my custom CUIx, and then having something similar to what Lee explains under the acaddoc.lsp section. But it's really up to you - whatever you feel more comfortable with (probably the Startup Suite's the least "nerdy").

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×