Make any Property a field with Python
Having a bit of fun, I wouldn’t use it in any production stuff. The idea is to make any property a field from any property, have the field evaluate as the property changes. Assuming the evaluator is loaded lultz.
import traceback from pyrx import Rx, Ge, Gi, Db, Ap, Ed, Brx print("added command - addevaluator") print("added command - remevaluator") print("added command - makefield") # (dumpallproperties (car(entsel))) # Vertical scale factor~Civil # 3D area~Civil # NetVolume~IFC2x3 #the evaluator class class BrxObjFieldEvaluator(Db.FieldEvaluator): def __init__(self, name, evalname): Db.FieldEvaluator.__init__(self, name, evalname) def compile(self, field: Db.Field, db: Db.Database, result: Db.AcValue): try: field.setData("fobjid", Db.AcValue(Db.ObjectId())) return Db.FieldEvalStatus.kSuccess except Exception as err: traceback.print_exception(err) return Db.FieldEvalStatus.kOtherError def evaluate(self, field: Db.Field, context, db, result: Db.AcValue): try: flag = Db.kEvaluatedChildren | Db.kStripOptions fcode = field.getFieldCode(Db.FieldCodeFlag(flag)).strip("\\BrxProp").strip() fobjid = field.getData("fobjid").getObjectId() isit, name = Brx.DbProperties.isValid(fobjid, fcode) if isit and fobjid.isValid(): result.setString(Brx.DbProperties.getValue(fobjid, name).format()) return Db.FieldEvalStatus.kSuccess return Db.FieldEvalStatus.kOtherError except Exception as err: traceback.print_exception(err) return Db.FieldEvalStatus.kOtherError #the one and only instance evaluator = BrxObjFieldEvaluator("Brx Properties", "BrxProp") # 1 -make the mtext # 2 -add the field, but it becomes nested so we will add the id later def makeMtext(db: Db.Database): ps, id, _ = Ed.Editor.entSel("\nSelect: ") ps, pnt = Ed.Editor.getPoint("\nPick Point: ") ps, prop = Ed.Editor.getString(1,"\nEnter a property: ") fld = Db.Field("%<\\BrxProp {}>%".format(prop.strip())) fld.evaluate() mt = Db.MText() mt.setLocation(pnt) db.addToCurrentspace(mt) fid = mt.setField(fld) return id, fid # add the object id def makeMtextField(db: Db.Database): mtid, fid = makeMtext(db) fld = Db.Field(fid) for idx in range(fld.childCount()): ch = fld.getChild(idx, Db.OpenMode.kForWrite) ch.setData("fobjid", Db.AcValue(mtid)) @Ap.Command() def makefield(): try: db = Db.curDb() makeMtextField(db) except Exception as err: print(err) @Ap.Command() def addevaluator(): try: engine: Db.FieldEngine = Db.FieldEngine.getEngine() engine.registerEvaluator(evaluator) except Exception as err: print(err) @Ap.Command() def remevaluator(): try: engine: Db.FieldEngine = Db.FieldEngine.getEngine() engine.unregisterEvaluator(evaluator) except Exception as err: print(err)
Comments
-
If Bricsys would only add the little red square in BRX, then it just might be possible to list all the properties, and add the fields to tables, leaders and stuff
0 -
Here’s another, an excel field evaluator, where you can reference a cell in a excel file. might be a good idea to cache the opened excel file in case multiple cells are hit. Just paste the fieldcode in any item the supports fields
import traceback from pyrx import Rx, Ge, Gi, Db, Ap, Ed import openpyxl as xl # [\XLSXField PATH SHEET CELL] # %<\XLSXField M:\\Dev\\Projects\\PyRxGit\\tests\\media\\testdata.xlsx|Show|A1>% # %<\XLSXField M:\\Dev\\Projects\\PyRxGit\\tests\\media\\testdata.xlsx|Show|B1>% # %<\XLSXField M:\\Dev\\Projects\\PyRxGit\\tests\\media\\testdata.xlsx|strings|A4>% print("added command - addxlevaluator") print("added command - remxlevaluator") class ExFieldEvaluator(Db.FieldEvaluator): def __init__(self, name, evalname): Db.FieldEvaluator.__init__(self, name, evalname) def evaluate( self, fld: Db.Field, ctx: int, db: Db.Database, res: Db.AcValue ) -> Db.FieldEvalStatus: try: fcode = fld.getFieldCode(Db.FieldCodeFlag.kFieldCode).strip("\\XLSXField") path, sheet, cell = fcode.split("|") workbook = xl.load_workbook(filename=path.strip(), read_only=True) worksheet = workbook[sheet] res.setString(str(worksheet[cell].value)) return Db.FieldEvalStatus.kSuccess except Exception as err: traceback.print_exception(err) return Db.FieldEvalStatus.kOtherError xlevaluator = ExFieldEvaluator("XLSX Field", "XLSXField") @Ap.Command() def addxlevaluator(): try: engine: Db.FieldEngine = Db.FieldEngine.getEngine() engine.registerEvaluator(xlevaluator) except Exception as err: print(err) @Ap.Command() def remxlevaluator(): try: engine: Db.FieldEngine = Db.FieldEngine.getEngine() engine.unregisterEvaluator(xlevaluator) except Exception as err: print(err)
enjoy
0 -
Wow - where do I learn how to wrangle a Pyton? Sounds a bit like:
I want to make old fashioned Groups one of the sort-by categories in Structure panel. It's not on the long (but catastrophically dysfunctional - non-scrollable - list, attached) and according to Support can't be added. Instead I've hacked Hyperlink as a top-level sort-by category, within which entities are listed under their usual Layer sort-by category as a sub-level in Structure Panel. Would prefer Groups as the top-level sort-by.
Could this be done in Python?
0 -
“where do I learn how to wrangle a Python”
The package is at
Watch the YouTube video on how to install
Still working on samples, but there’s some here
Its helpful if you already know one of the CAD APIs, VB, .NET or BRX
“Structure panel”
I’m not too familiar with the Structure panel, but it seems it would be possible to build your own palette organized the way you want. Skill level is intermediate, so it might be best to learn how to iterate the drawing database, play with wxPython GUI first
0 -
Well, it's something I intend to propose to Brics devs, to allow Structure panel to have unlimited(?) nested levels, so you can switch on/off e.g. 'Existing' vs 'Proposed', or subsets of e.g. Walls vs Floors vs Windows, or subsubsets e.g. Floor conc vs Floor insulation - instead of, as it stands, only a single level , either byLayer, or byBlock or whatever (remembering that Brics have withdrawn the ability to Show/Hide within a Block). I've found that by hacking 'Hyperlink' as a Sort-by Property, I can create a 2-level Structure panel - first byHyperlink, then within that, byLayer. byGroup could have been ideal, and are already nestable, but Structure panel doesn't recognise Groups.
0