| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | """ |
| | The purpose of this file is to collect some handy functions. The reason they |
| | are not in Path.Base.Utils (and there is this confusing naming going on) is that |
| | PathUtils depends on PathJob. Which makes it impossible to use the functions |
| | and classes defined there in PathJob. |
| | |
| | So if you add to this file and think about importing anything from PathScripts |
| | other than Path.Log, then it probably doesn't belong here. |
| | """ |
| |
|
| | import FreeCAD |
| | import Path |
| |
|
| | translate = FreeCAD.Qt.translate |
| |
|
| | if False: |
| | Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule()) |
| | Path.Log.trackModule(Path.Log.thisModule()) |
| | else: |
| | Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule()) |
| |
|
| |
|
| | def _getProperty(obj, prop): |
| | o = obj |
| | attr = obj |
| | name = None |
| | for name in prop.split("."): |
| | o = attr |
| | if not hasattr(o, name): |
| | break |
| | attr = getattr(o, name) |
| |
|
| | if o == attr: |
| | Path.Log.debug(translate("PathGui", "%s has no property %s (%s)") % (obj.Label, prop, name)) |
| | return (None, None, None) |
| |
|
| | |
| | return (o, attr, name) |
| |
|
| |
|
| | def getProperty(obj, prop): |
| | """getProperty(obj, prop) ... answer obj's property defined by its canonical name.""" |
| | o, attr, name = _getProperty(obj, prop) |
| | return attr |
| |
|
| |
|
| | def getPropertyValueString(obj, prop): |
| | """getPropertyValueString(obj, prop) ... answer a string representation of an object's property's value.""" |
| | attr = getProperty(obj, prop) |
| | if hasattr(attr, "UserString"): |
| | return attr.UserString |
| | return str(attr) |
| |
|
| |
|
| | def setProperty(obj, prop, value): |
| | """setProperty(obj, prop, value) ... set the property value of obj's property defined by its canonical name.""" |
| | o, attr, name = _getProperty(obj, prop) |
| | if attr is not None and isinstance(value, str): |
| | if isinstance(attr, bool): |
| | value = value.lower() in ["true", "1", "yes", "ok"] |
| | elif isinstance(attr, int): |
| | value = int(value, 0) |
| | if o and name: |
| | setattr(o, name, value) |
| |
|
| |
|
| | |
| | NotValidBaseTypeIds = [] |
| |
|
| |
|
| | def isValidBaseObject(obj): |
| | """isValidBaseObject(obj) ... returns true if the object can be used as a base for a job.""" |
| | if hasattr(obj, "getParentGeoFeatureGroup") and obj.getParentGeoFeatureGroup(): |
| | |
| | Path.Log.debug("%s is inside a geo feature group" % obj.Label) |
| | return False |
| | if hasattr(obj, "BitBody") and hasattr(obj, "ShapeName"): |
| | |
| | return False |
| | if hasattr(obj, "ToolBitID"): |
| | return False |
| | if any(hasattr(ob, "ToolBitID") for ob in getattr(obj, "InListRecursive", [])): |
| | return False |
| | if obj.TypeId in NotValidBaseTypeIds: |
| | Path.Log.debug("%s is blacklisted (%s)" % (obj.Label, obj.TypeId)) |
| | return False |
| | if hasattr(obj, "Sheets") or hasattr(obj, "TagText"): |
| | Path.Log.debug("%s is not an Arch.Panel" % (obj.Label)) |
| | return False |
| | import Part |
| |
|
| | return not Part.getShape(obj).isNull() |
| |
|
| |
|
| | def isSolid(obj): |
| | """isSolid(obj) ... return True if the object is a valid solid.""" |
| | import Part |
| |
|
| | shape = Part.getShape(obj) |
| | return not shape.isNull() and shape.Volume and shape.isClosed() |
| |
|
| |
|
| | def opProperty(op, prop, default=None): |
| | """opProperty(op, prop) ... return the value of property prop of the underlying operation (or None if prop does not exist)""" |
| | if hasattr(op, prop): |
| | return getattr(op, prop) |
| | if hasattr(op, "Base"): |
| | return opProperty(op.Base, prop, default) |
| | return default |
| |
|
| |
|
| | def toolControllerForOp(op): |
| | """toolControllerForOp(op) ... return the tool controller used by the op. |
| | If the op doesn't have its own tool controller but has a Base object, return its tool controller. |
| | Otherwise return None.""" |
| | return opProperty(op, "ToolController") |
| |
|
| |
|
| | def coolantModeForOp(op): |
| | """coolantModeForOp(op) ... return the coolant mode used by the op. |
| | If the op doesn't have its own coolant mode but has a Base object, return its coolant mode. |
| | Otherwise return "None".""" |
| | return opProperty(op, "CoolantMode", "None") |
| |
|
| |
|
| | def activeForOp(op): |
| | """activeForOp(op) ... return the active property used by the op. |
| | If the op doesn't have its own active property but has a Base object, return its active property. |
| | Otherwise return True.""" |
| | return opProperty(op, "Active", True) |
| |
|
| |
|
| | def getPublicObject(obj): |
| | """getPublicObject(obj) ... returns the object which should be used to reference a feature of the given object.""" |
| | if hasattr(obj, "getParentGeoFeatureGroup"): |
| | body = obj.getParentGeoFeatureGroup() |
| | if body: |
| | return getPublicObject(body) |
| | return obj |
| |
|
| |
|
| | def clearExpressionEngine(obj): |
| | """clearExpressionEngine(obj) ... removes all expressions from obj. |
| | |
| | There is currently a bug that invalidates the DAG if an object |
| | is deleted that still has one or more expressions attached to it. |
| | Use this function to remove all expressions before deletion.""" |
| | if hasattr(obj, "ExpressionEngine"): |
| | for attr, expr in obj.ExpressionEngine: |
| | obj.setExpression(attr, None) |
| |
|