def Activated(self): from draftutils.messages import _log if hasattr(Gui, "draftToolBar"): Gui.draftToolBar.Activated() if hasattr(Gui, "Snapper"): Gui.Snapper.show() class EnVisWatcher: def __init__(self, cmds, name, invert=False): self.commands = cmds self.title = name self.invert = invert def shouldShow(self): if self.invert: return (App.ActiveDocument is not None) and ( Gui.Selection.getSelection() != []) else: return (App.ActiveDocument is not None) and (not Gui.Selection.getSelection()) Gui.Control.addTaskWatcher([ EnVisWatcher(self.draftingtools + self.annotationtools, "2D geometry"), EnVisWatcher(self.bimtools, "3D/BIM geometry"), EnVisWatcher(self.modify, "Modify", invert=True) ]) _log("EnVis workbench activated")
def Deactivated(self): from draftutils.messages import _log if hasattr(Gui, "draftToolBar"): Gui.draftToolBar.Deactivated() if hasattr(Gui, "Snapper"): Gui.Snapper.hide() Gui.Control.clearTaskWatcher() _log("EnVis workbench deactivated")
def Activated(self): """Execute when the command is called. Log the command name to the log file and console. Also update the `doc` attribute. """ self.doc = App.activeDocument() _log("Document: {}".format(self.doc.Label)) _log("GuiCommand: {}".format(self.command_name)) _msg("{}".format(16 * "-")) _msg("GuiCommand: {}".format(self.command_name))
def Activated(self): """Execute when the command is called. We add callbacks that connect the 3D view with the widgets of the task panel. """ _log("GuiCommand: {}".format(self.command_name)) #_msg("{}".format(16*"-")) #_msg("GuiCommand: {}".format(self.command_name)) # self.location = coin.SoLocation2Event.getClassTypeId() self.mouse_event = coin.SoMouseButtonEvent.getClassTypeId() self.view = Draft.get3DView() # self.callback_move = \ # self.view.addEventCallbackPivy(self.location, self.move) self.callback_click = \ self.view.addEventCallbackPivy(self.mouse_event, self.click) self.ui = task_orthoarray.TaskPanelOrthoArray() # The calling class (this one) is saved in the object # of the interface, to be able to call a function from within it. self.ui.source_command = self # Gui.Control.showDialog(self.ui) todo.ToDo.delay(Gui.Control.showDialog, self.ui)
def print_header(name, description, debug=True): """Print a line to the console when something is called, and log it. Parameters ---------- name: str The name of the function or class that is being called. This `name` will be logged in the log file, so if there are problems the log file can be investigated for clues. description: str Arbitrary text that will be printed to the console when the function or class is called. debug: bool, optional It defaults to `True`. If it is `False` the `description` will not be printed to the console. On the other hand the `name` will always be logged. """ _log(name) if debug: _msg(16 * "-") _msg(description)
def doTasks(): """Execute the commands stored in the lists. The lists are `itinerary`, `commitlist` and `afteritinerary`. """ if _DEBUG: _msg("Debug: doing delayed tasks.\n" "itinerary: {0}\n" "commitlist: {1}\n" "afteritinerary: {2}\n".format(todo.itinerary, todo.commitlist, todo.afteritinerary)) try: for f, arg in ToDo.itinerary: try: if _DEBUG_inner: _msg("Debug: executing.\n" "function: {}\n".format(f)) if arg or (arg is False): f(arg) else: f() except Exception: _log(traceback.format_exc()) _err(traceback.format_exc()) wrn = ("ToDo.doTasks, Unexpected error:\n" "{0}\n" "in {1}({2})".format(sys.exc_info()[0], f, arg)) _wrn(wrn) except ReferenceError: _wrn("Debug: ToDo.doTasks: " "queue contains a deleted object, skipping") ToDo.itinerary = [] if ToDo.commitlist: for name, func in ToDo.commitlist: if six.PY2: if isinstance(name, six.text_type): name = name.encode("utf8") if _DEBUG_inner: _msg("Debug: committing.\n" "name: {}\n".format(name)) try: name = str(name) App.activeDocument().openTransaction(name) if isinstance(func, list): for string in func: Gui.doCommand(string) else: func() App.activeDocument().commitTransaction() except Exception: _log(traceback.format_exc()) _err(traceback.format_exc()) wrn = ("ToDo.doTasks, Unexpected error:\n" "{0}\n" "in {1}".format(sys.exc_info()[0], func)) _wrn(wrn) # Restack Draft screen widgets after creation if hasattr(Gui, "Snapper"): Gui.Snapper.restack() ToDo.commitlist = [] for f, arg in ToDo.afteritinerary: try: if _DEBUG_inner: _msg("Debug: executing after.\n" "function: {}\n".format(f)) if arg: f(arg) else: f() except Exception: _log(traceback.format_exc()) _err(traceback.format_exc()) wrn = ("ToDo.doTasks, Unexpected error:\n" "{0}\n" "in {1}({2})".format(sys.exc_info()[0], f, arg)) _wrn(wrn) ToDo.afteritinerary = []
def __init__(self): self.name = "Orthogonal array" _log(_tr("Task panel:") + " {}".format(_tr(self.name))) # The .ui file must be loaded into an attribute # called `self.form` so that it is displayed in the task panel. ui_file = ":/ui/TaskPanel_OrthoArray.ui" self.form = Gui.PySideUic.loadUi(ui_file) icon_name = "Draft_Array" svg = ":/icons/" + icon_name pix = QtGui.QPixmap(svg) icon = QtGui.QIcon.fromTheme(icon_name, QtGui.QIcon(svg)) self.form.setWindowIcon(icon) self.form.setWindowTitle(_tr(self.name)) self.form.label_icon.setPixmap(pix.scaled(32, 32)) # ------------------------------------------------------------------- # Default values for the internal function, # and for the task panel interface start_x = U.Quantity(100.0, App.Units.Length) start_y = start_x start_z = start_x length_unit = start_x.getUserPreferred()[2] self.v_x = App.Vector(start_x.Value, 0, 0) self.v_y = App.Vector(0, start_y.Value, 0) self.v_z = App.Vector(0, 0, start_z.Value) self.form.input_X_x.setProperty('rawValue', self.v_x.x) self.form.input_X_x.setProperty('unit', length_unit) self.form.input_X_y.setProperty('rawValue', self.v_x.y) self.form.input_X_y.setProperty('unit', length_unit) self.form.input_X_z.setProperty('rawValue', self.v_x.z) self.form.input_X_z.setProperty('unit', length_unit) self.form.input_Y_x.setProperty('rawValue', self.v_y.x) self.form.input_Y_x.setProperty('unit', length_unit) self.form.input_Y_y.setProperty('rawValue', self.v_y.y) self.form.input_Y_y.setProperty('unit', length_unit) self.form.input_Y_z.setProperty('rawValue', self.v_y.z) self.form.input_Y_z.setProperty('unit', length_unit) self.form.input_Z_x.setProperty('rawValue', self.v_z.x) self.form.input_Z_x.setProperty('unit', length_unit) self.form.input_Z_y.setProperty('rawValue', self.v_z.y) self.form.input_Z_y.setProperty('unit', length_unit) self.form.input_Z_z.setProperty('rawValue', self.v_z.z) self.form.input_Z_z.setProperty('unit', length_unit) self.n_x = 2 self.n_y = 2 self.n_z = 1 self.form.spinbox_n_X.setValue(self.n_x) self.form.spinbox_n_Y.setValue(self.n_y) self.form.spinbox_n_Z.setValue(self.n_z) self.fuse = utils.get_param("Draft_array_fuse", False) self.use_link = utils.get_param("Draft_array_Link", True) self.form.checkbox_fuse.setChecked(self.fuse) self.form.checkbox_link.setChecked(self.use_link) # ------------------------------------------------------------------- # Some objects need to be selected before we can execute the function. self.selection = None # This is used to test the input of the internal function. # It should be changed to True before we can execute the function. self.valid_input = False self.set_widget_callbacks() self.tr_true = QT_TRANSLATE_NOOP("Draft", "True") self.tr_false = QT_TRANSLATE_NOOP("Draft", "False")
def __init__(self): self.name = "Circular array" _log(_tr("Task panel:") + " {}".format(_tr(self.name))) # The .ui file must be loaded into an attribute # called `self.form` so that it is displayed in the task panel. ui_file = ":/ui/TaskPanel_CircularArray.ui" self.form = Gui.PySideUic.loadUi(ui_file) icon_name = "Draft_CircularArray" svg = ":/icons/" + icon_name pix = QtGui.QPixmap(svg) icon = QtGui.QIcon.fromTheme(icon_name, QtGui.QIcon(svg)) self.form.setWindowIcon(icon) self.form.setWindowTitle(_tr(self.name)) self.form.label_icon.setPixmap(pix.scaled(32, 32)) # ------------------------------------------------------------------- # Default values for the internal function, # and for the task panel interface start_distance = U.Quantity(50.0, App.Units.Length) length_unit = start_distance.getUserPreferred()[2] self.r_distance = 2 * start_distance.Value self.tan_distance = start_distance.Value self.form.spinbox_r_distance.setProperty('rawValue', self.r_distance) self.form.spinbox_r_distance.setProperty('unit', length_unit) self.form.spinbox_tan_distance.setProperty('rawValue', self.tan_distance) self.form.spinbox_tan_distance.setProperty('unit', length_unit) self.number = 3 self.symmetry = 1 self.form.spinbox_number.setValue(self.number) self.form.spinbox_symmetry.setValue(self.symmetry) # TODO: the axis is currently fixed, it should be editable # or selectable from the task panel self.axis = App.Vector(0, 0, 1) start_point = U.Quantity(0.0, App.Units.Length) length_unit = start_point.getUserPreferred()[2] self.center = App.Vector(start_point.Value, start_point.Value, start_point.Value) self.form.input_c_x.setProperty('rawValue', self.center.x) self.form.input_c_x.setProperty('unit', length_unit) self.form.input_c_y.setProperty('rawValue', self.center.y) self.form.input_c_y.setProperty('unit', length_unit) self.form.input_c_z.setProperty('rawValue', self.center.z) self.form.input_c_z.setProperty('unit', length_unit) self.fuse = utils.get_param("Draft_array_fuse", False) self.use_link = utils.get_param("Draft_array_Link", True) self.form.checkbox_fuse.setChecked(self.fuse) self.form.checkbox_link.setChecked(self.use_link) # ------------------------------------------------------------------- # Some objects need to be selected before we can execute the function. self.selection = None # This is used to test the input of the internal function. # It should be changed to True before we can execute the function. self.valid_input = False self.set_widget_callbacks() self.tr_true = QT_TRANSLATE_NOOP("Draft", "True") self.tr_false = QT_TRANSLATE_NOOP("Draft", "False") # The mask is not used at the moment, but could be used in the future # by a callback to restrict the coordinates of the pointer. self.mask = ""
def make_arc_3points(points, placement=None, face=False, support=None, map_mode="Deactivated", primitive=False): """Draw a circular arc defined by three points in the circumference. Parameters ---------- points: list of Base::Vector3 A list that must be three points. placement: Base::Placement, optional It defaults to `None`. It is a placement, comprised of a `Base` (`Base::Vector3`), and a `Rotation` (`Base::Rotation`). If it exists it moves the center of the new object to the point indicated by `placement.Base`, while `placement.Rotation` is ignored so that the arc keeps the same orientation with which it was created. If both `support` and `placement` are given, `placement.Base` is used for the `AttachmentOffset.Base`, and again `placement.Rotation` is ignored. face: bool, optional It defaults to `False`. If it is `True` it will create a face in the closed arc. Otherwise only the circumference edge will be shown. support: App::PropertyLinkSubList, optional It defaults to `None`. It is a list containing tuples to define the attachment of the new object. A tuple in the list needs two elements; the first is an external object, and the second is another tuple with the names of sub-elements on that external object likes vertices or faces. :: support = [(obj, ("Face1"))] support = [(obj, ("Vertex1", "Vertex5", "Vertex8"))] This parameter sets the `Support` property but it only really affects the position of the new object when the `map_mode` is set to other than `'Deactivated'`. map_mode: str, optional It defaults to `'Deactivated'`. It defines the type of `'MapMode'` of the new object. This parameter only works when a `support` is also provided. Example: place the new object on a face or another object. :: support = [(obj, ("Face1"))] map_mode = 'FlatFace' Example: place the new object on a plane created by three vertices of an object. :: support = [(obj, ("Vertex1", "Vertex5", "Vertex8"))] map_mode = 'ThreePointsPlane' primitive: bool, optional It defaults to `False`. If it is `True`, it will create a Part primitive instead of a Draft object. In this case, `placement`, `face`, `support`, and `map_mode` are ignored. Returns ------- Part::Part2DObject or Part::Feature The new arc object. Normally it returns a parametric Draft object (`Part::Part2DObject`). If `primitive` is `True`, it returns a basic `Part::Feature`. """ _log("make_arc_3points") _msg(16 * "-") _msg(_tr("Arc by 3 points")) if not isinstance(points, (list, tuple)): _err(_tr("Wrong input: must be list or tuple of three points.")) return None if len(points) != 3: _err(_tr("Wrong input: must be three points.")) return None if placement is not None: if not isinstance(placement, App.Placement): _err(_tr("Wrong input: incorrect placement")) return None p1, p2, p3 = points _edge = Part.Arc(p1, p2, p3) edge = _edge.toShape() radius = edge.Curve.Radius center = edge.Curve.Center _msg("p1: {}".format(p1)) _msg("p2: {}".format(p2)) _msg("p3: {}".format(p3)) _msg(_tr("Radius: ") + "{}".format(radius)) _msg(_tr("Center: ") + "{}".format(center)) if primitive: obj = App.ActiveDocument.addObject("Part::Feature", "Arc") obj.Shape = edge _msg(_tr("Primitive object")) return obj rot = App.Rotation(edge.Curve.XAxis, edge.Curve.YAxis, edge.Curve.Axis, "ZXY") _placement = App.Placement(center, rot) start = edge.FirstParameter end = math.degrees(edge.LastParameter) obj = Draft.makeCircle(radius, placement=_placement, face=face, startangle=start, endangle=end, support=support) if App.GuiUp: gui_utils.autogroup(obj) original_placement = obj.Placement if placement and not support: obj.Placement.Base = placement.Base _msg(_tr("Final placement: ") + "{}".format(obj.Placement)) if face: _msg(_tr("Face: True")) if support: _msg(_tr("Support: ") + "{}".format(support)) obj.MapMode = map_mode _msg(_tr("Map mode: " + "{}".format(map_mode))) if placement: obj.AttachmentOffset.Base = placement.Base obj.AttachmentOffset.Rotation = original_placement.Rotation _msg(_tr("Attachment offset: {}".format(obj.AttachmentOffset))) _msg(_tr("Final placement: ") + "{}".format(obj.Placement)) return obj
def Activated(self, name="None", noplanesetup=False, is_subtool=False): """Execute when the command is called. If an active Gui Command exists, it will call the `finish` method of it to terminate it. If no active Gui Command exists, it will proceed with configuration of the tool. The child class that subclasses this class then should continue with its own Activated method. Parameters ---------- name: str, optional It defaults to `'None'`. It is the `featureName` of the object, to know what is being run. noplanesetup: bool, optional It defaults to `False`. If it is `False` it will set up the working plane by running `App.DraftWorkingPlane.setup()`. is_subtool: bool, optional It defaults to `False`. This is set to `True` when we want to modify an object by using the mechanism of a `subtool`, introduced through the `Draft_SubelementHighlight` command. That is, first we run `Draft_SubelementHighlight` then we can use `Draft_Move` while setting `is_subtool` to `True`. """ if App.activeDraftCommand and not is_subtool: App.activeDraftCommand.finish() # The Part module is first initialized when using any Gui Command # for the first time. global Part, DraftGeomUtils import Part import DraftGeomUtils self.ui = None self.call = None self.support = None self.point = None self.commitList = [] self.doc = App.ActiveDocument if not self.doc: self.finish() return App.activeDraftCommand = self self.view = gui_utils.get_3d_view() self.ui = Gui.draftToolBar self.featureName = name self.ui.sourceCmd = self self.ui.setTitle(name) self.ui.show() if not noplanesetup: App.DraftWorkingPlane.setup() self.node = [] self.pos = [] self.constrain = None self.obj = None self.extendedCopy = False self.ui.setTitle(name) self.planetrack = None if utils.get_param("showPlaneTracker", False): self.planetrack = trackers.PlaneTracker() if hasattr(Gui, "Snapper"): Gui.Snapper.setTrackers() _log("GuiCommand: {}".format(self.featureName)) _msg("{}".format(16*"-")) _msg("GuiCommand: {}".format(self.featureName))
def Initialize(self): if not hasattr(Gui, "listCommands"): Gui.listCommands = Gui.Command.listAll from PySide.QtCore import QT_TRANSLATE_NOOP import DraftTools import Arch import envis.commands from draftutils.messages import _log try: Gui.activateWorkbench("BIMWorkbench") except KeyError: print( "BIM Workbench not available. Some commands will be missing.") self.draftingtools = [ "BIM_Sketch", "Draft_Line", "Draft_Wire", "Draft_Circle", "Draft_Arc", "Draft_Arc_3Points", "Draft_Ellipse", "Draft_Polygon", "Draft_Rectangle", "Draft_Point" ] self.annotationtools = [ "Draft_Text", "Draft_ShapeString", "Draft_Dimension", "Draft_Label", "Arch_Axis", "Arch_AxisSystem", "Arch_Grid", "Arch_SectionPlane" ] self.bimtools = [ "Arch_Site", "Arch_Building", "Arch_Floor", "Arch_Space", "Separator", "Arch_Wall", "BIM_Slab", "BIM_Door", "Arch_Window", "Arch_Roof", "Arch_Panel", "Arch_Frame", "Separator", "BIM_Box", "Draft_Facebinder", "BIM_Library", "Arch_Component" ] self.modify = [ "Draft_Move", "BIM_Copy", "Draft_Rotate", "BIM_Clone", "BIM_Unclone", "Draft_Offset", "BIM_Offset2D", "Draft_Trimex", "Draft_Join", "Draft_Split", "Draft_Scale", "Draft_Stretch", "BIM_Rewire", "BIM_Glue", "Draft_Upgrade", "Draft_Downgrade", "Draft_Draft2Sketch", "Arch_CutPlane", "Arch_Add", "Arch_Remove", "BIM_Reextrude", "BIM_Cut", "Draft_Shape2DView" ] self.snap = [ 'Draft_ToggleGrid', 'Draft_Snap_Lock', 'Draft_Snap_Midpoint', 'Draft_Snap_Perpendicular', 'Draft_Snap_Grid', 'Draft_Snap_Intersection', 'Draft_Snap_Parallel', 'Draft_Snap_Endpoint', 'Draft_Snap_Angle', 'Draft_Snap_Center', 'Draft_Snap_Extension', 'Draft_Snap_Near', 'Draft_Snap_Ortho', 'Draft_Snap_Special', 'Draft_Snap_Dimensions', 'Draft_Snap_WorkingPlane', 'BIM_SetWPTop', 'BIM_SetWPFront', 'BIM_SetWPSide' ] self.manage = [ "BIM_Setup", "BIM_Project", "BIM_Views", "BIM_Windows", "BIM_IfcElements", "BIM_IfcQuantities", "BIM_IfcProperties", "BIM_Classification", "BIM_Material", "Arch_Schedule", "BIM_Preflight", "BIM_Layers" ] self.utils = [ "BIM_TogglePanels", "BIM_Trash", "BIM_WPView", "Draft_Slope", "Draft_WorkingPlaneProxy", "Draft_AddConstruction", "Arch_SplitMesh", "Arch_MeshToShape", "Arch_SelectNonSolidMeshes", "Arch_RemoveShape", "Arch_CloseHoles", "Arch_MergeWalls", "Arch_Check", "Arch_ToggleIfcBrepFlag", "Arch_ToggleSubs", "Arch_Survey", "BIM_Diff", "BIM_IfcExplorer" ] self.envis = [ "EnVis_Import", "EnVis_BruttoFl", "EnVis_Setup", "EnVis_SelectRelated" ] # post-0.18 tools if "Arch_Project" in Gui.listCommands(): self.bimtools.insert(0, "Arch_Project") if "Arch_Reference" in Gui.listCommands(): self.bimtools.insert(-5, "Arch_Reference") if "Draft_Arc_3Points" in Gui.listCommands(): self.draftingtools.insert(5, "Draft_Arc_3Points") if "Arch_Truss" in Gui.listCommands(): self.bimtools.insert( self.bimtools.index("Arch_Frame") + 1, "Arch_Truss") if "Arch_CurtainWall" in Gui.listCommands(): self.bimtools.insert( self.bimtools.index("Arch_Wall") + 1, "Arch_CurtainWall") # try to load bimbots try: import bimbots except ImportError: pass else: class BIMBots: def GetResources(self): return bimbots.get_plugin_info() def Activated(self): bimbots.launch_ui() Gui.addCommand('BIMBots', BIMBots()) self.utils.append("BIMBots") # load Reporting try: import report except ImportError: pass else: if "Report_Create" in Gui.listCommands(): self.manage[self.manage.index( "Arch_Schedule")] = "Report_Create" # load webtools try: import BIMServer, Git, Sketchfab except ImportError: pass else: self.utils.extend( ["WebTools_Git", "WebTools_BimServer", "WebTools_Sketchfab"]) # create toolbars self.appendToolbar(QT_TRANSLATE_NOOP("BIM", "Drafting tools"), self.draftingtools) self.appendToolbar(QT_TRANSLATE_NOOP("BIM", "3D/BIM tools"), self.bimtools) self.appendToolbar(QT_TRANSLATE_NOOP("BIM", "Annotation tools"), self.annotationtools) self.appendToolbar(QT_TRANSLATE_NOOP("BIM", "Modification tools"), self.modify) self.appendToolbar("EnVis tools", self.envis) # create menus self.appendMenu(QT_TRANSLATE_NOOP("BIM", "&2D Drafting"), self.draftingtools) self.appendMenu(QT_TRANSLATE_NOOP("BIM", "&3D/BIM"), self.bimtools) self.appendMenu(QT_TRANSLATE_NOOP("BIM", "&Annotation"), self.annotationtools) self.appendMenu(QT_TRANSLATE_NOOP("BIM", "&Snapping"), self.snap) self.appendMenu(QT_TRANSLATE_NOOP("BIM", "&Modify"), self.modify) self.appendMenu(QT_TRANSLATE_NOOP("BIM", "&Manage"), self.manage) self.appendMenu(QT_TRANSLATE_NOOP("BIM", "&Utils"), self.utils) self.appendMenu("EnVis", self.envis) # load Arch & Draft preference pages if hasattr(Gui, "draftToolBar"): if not hasattr(Gui.draftToolBar, "loadedArchPreferences"): import Arch_rc Gui.addPreferencePage(":/ui/preferences-arch.ui", "Arch") Gui.addPreferencePage(":/ui/preferences-archdefaults.ui", "Arch") Gui.draftToolBar.loadedArchPreferences = True if not hasattr(Gui.draftToolBar, "loadedPreferences"): import Draft_rc Gui.addPreferencePage(":/ui/preferences-draft.ui", "Draft") Gui.addPreferencePage(":/ui/preferences-draftsnap.ui", "Draft") Gui.addPreferencePage(":/ui/preferences-draftvisual.ui", "Draft") Gui.addPreferencePage(":/ui/preferences-drafttexts.ui", "Draft") Gui.draftToolBar.loadedPreferences = True _log('Loading EnVis module... done') Gui.updateLocale()
def Activated(self): _log("GuiCommand: {}".format(self.command_name))