Multiple job
Got a lot of DWG from eplan.
I have some script (scr) and some LISP for doing what I want but I'm stuck with LeeMac's Attcol and it's dialogue.
Here is what I want:
Create a new Layer, let say layer 800
Move all items to layer 800
Delete all layers except layer 0 and layer 800 and move remaining blocks to layer 800. (Like Change when doing it by Drawing Explorer - Layers)
Change ALL object, including nested block, as well as all attributes to colour ByLayer or (color 7)
Comments
-
Python is a cool option for stuff like this, a one-off script with the power of BRX without having to compile
If you’re running V24-v25 check out pyrx
import traceback import wx import os, pathlib from pyrx import Db, Ap def addLayer(sidedb: Db.Database, name: str): lt = Db.LayerTable(sidedb.layerTableId()) if lt.has(name): return lt.getAt(name) clr = Db.Color() clr.setColorIndex(3) layer = Db.LayerTableRecord() layer.setName(name) layer.setColor(clr) lt.upgradeOpen() return lt.add(layer) def moveModelSpaceEntsToLayer(sidedb: Db.Database, lid: Db.ObjectId): model = Db.BlockTableRecord(sidedb.modelSpaceId()) for id in model.objectIds(): ent = Db.Entity(id, Db.OpenMode.kForWrite) ent.setLayer(lid) def moveBlockEntsToLayer(sidedb: Db.Database): bt = Db.BlockTable(sidedb.blockTableId()) for _name, id in bt.toDict().items(): block = Db.BlockTableRecord(id) # skip a name if you want if block.isLayout(): continue if block.isFromExternalReference(): continue for id in block.objectIds(): ent = Db.Entity(id, Db.OpenMode.kForWrite) ent.setColorIndex(256) # by layer ent.setLayer("0") def removeLayersExcept(sidedb: Db.Database, keep: list[str]): lt = Db.LayerTable(sidedb.layerTableId()) for name, id in lt.asDict().items(): if name in keep: continue layer = Db.LayerTableRecord(id, Db.OpenMode.kForWrite) try: layer.erase() except Exception as err: print("cannot delete {}".format(name)) # do some stuff def worker(sidedb: Db.Database): lid = addLayer(sidedb, "800") moveModelSpaceEntsToLayer(sidedb, lid) moveBlockEntsToLayer(sidedb) removeLayersExcept(sidedb, ["0", "800"]) # reads the .dwg can calls a worker function and provides a scope def openSideDatabase(path, worker): sideDb = Db.Database(False, True) # no doc sideDb.readDwgFile(path) sideDb.closeInput(True) worker(sideDb) sideDb.saveAs(path) # get dwg paths from dir (top level only) using wxPython def getDwgFiles(): paths = [] dlg = wx.DirDialog(None, "Choose directory", "", wx.DD_DIR_MUST_EXIST) if dlg.ShowModal() != wx.ID_OK: print("You Cancelled The Dialog!") return fnames = next(os.walk(dlg.GetPath()), (None, None, []))[2] dwgex = ".dwg".casefold() for fname in fnames: ext = pathlib.Path(fname).suffix.casefold() if ext != dwgex: continue paths.append("{}\\{}".format(dlg.GetPath(), fname)) return paths @Ap.Command() def doit() -> None: try: for _item in getDwgFiles(): print("\nProccessing {}".format(_item)) openSideDatabase(_item, worker) print("done") except Exception as err: traceback.print_exception(err)
0 -
A couple of snippets of code.
(command "-layer" "m" "800" "C" 7 "" "")
(command "chprop" "all" "" "LA" "800" "Color" "Bylayer" "")
(setq doc (vla-get-activedocument (vlax-get-acad-object))) ; open database
(vlax-for block (vla-get-blocks doc)
(if (not (wcmatch (strcase (vla-get-name block) t) "_space"))
(vlax-for ent block
(vla-put-layer ent "800")
(vla-put-color ent "Bylayer")
(vla-put-linetype ent "Bylayer")
(vla-put-lineweight ent aclnwtbyblock)
)
)
)I would do a purge for the layers only, may need to do twice.
0 -
Thanks. How to use this? I got v21.2.07
0 -
Thanks!
First I do a purge of all layers and all blocks.
Then rename one (1) blockname to a "proper" blockname.
Then I do a "changetag" by @VirgilAbove is a absolute minimum for me to have any use of the dwgs.
After that = as topic here.(command "-layer" "m" "800" "C" 7 "" "") (command "chprop" "all" "" "LA" "800" "Color" "Bylayer" "")
Works nice. (kind of how I already do, but this is better)
(vla-put-color ent "Bylayer")
Does not work.
; error : Automation Error DISP_E_PARAMNOTOPTIONAL; [IAcadBlockReference] Required argument is not optional for [COLOR] property.But this works
(vla-put-color ent 7)
Still - all attributes is colored
This works:
But then I have to use that dialogue, for each file
0 -
If I use a script as scr (yes I assume also as a LISP?) I can use like
Attedit
Y
*
*
*
All
C
7
Nand so on for each attribute.
How to write code so the C7N loops as long as there a next attribute to edit?
0 -
Found this
I then edit that as
(defun c:ATR (/ com val) (initget 1 "Height Angle Style Layer Color") (setq com "Color") (setq val "7") (prompt "\nSelect Attributes by Crossing Window: ") (command ".attedit" "y" "" "" "*" "all" ) (while (> (getvar "cmdactive") 0) (command com val "n") ) (princ) )
If I run ATR it does the job to change color for all attributes.
If I call the atr.lsp from a scr-script - it never stops. How to prevent that?
(I have a application where I can batch-select files and then run a scr for each file so my idea was to just call the lisp, as I do with "changetag")
0