def activeContainer(): '''activeContainer(): returns active container. If there is an active body, it is returned as active container. ActivePart is ignored. If there is no active body, active Part is returned. If there is no active Part either, active Document is returned. If no active document, None is returned.''' import FreeCAD as App import FreeCADGui as Gui if hasattr(App, "ActiveContainer"): return App.ActiveContainer.Object if Gui.ActiveDocument is None: return None if Gui.ActiveDocument.ActiveView is None: raise NoActiveContainerError("ActiveDocument is not none, but viewer is None. Can't determine active container.") activeBody = Gui.ActiveDocument.ActiveView.getActiveObject("pdbody") activePart = Gui.ActiveDocument.ActiveView.getActiveObject("part") if activeBody: return screen(activeBody) elif activePart: return screen(activePart) else: return App.ActiveDocument
def activeContainer(): '''activeContainer(): returns active container. If there is an active body, it is returned as active container. ActivePart is ignored. If there is no active body, active Part is returned. If there is no active Part either, active Document is returned. If no active document, None is returned.''' import FreeCAD as App import FreeCADGui as Gui if hasattr(App, "ActiveContainer"): return App.ActiveContainer.Object if Gui.ActiveDocument is None: return None if Gui.ActiveDocument.ActiveView is None: raise NoActiveContainerError( "ActiveDocument is not none, but viewer is None. Can't determine active container." ) activeBody = Gui.ActiveDocument.ActiveView.getActiveObject("pdbody") activePart = Gui.ActiveDocument.ActiveView.getActiveObject("part") if activeBody: return screen(activeBody) elif activePart: return screen(activePart) else: return App.ActiveDocument
def addObjectTo(container, feature, b_advance_tip = True): container = screen(container) feature = screen(feature) cnt_old = getContainer(feature) if not cnt_old.isDerivedFrom('App::Document') and cnt_old is not container: raise AlreadyInContainerError(u"Object '{obj}' is already in '{cnt_old}'. Cannot add it to '{cnt_new}'" .format(obj= feature.Label, cnt_old= cnt_old.Label, cnt_new= container.Label)) if cnt_old is container: return #nothing to do if feature is container : raise ContainerError(u"Attempting to add {feat} to itself. Feature can't contain itself.".format(feat= feature.Label)) if container.hasExtension("App::GroupExtension"): #container.addObject(feature) container.Group = container.Group + [feature] if b_advance_tip: try: container.Proxy.advanceTip(container, feature) except AttributeError: pass except Exception as err: App.Console.printError(u"Tip advancement routine failed with an error when adding {feat} to {cnt}. {err}" .format(feat= feature.Label, cnt= container.Label, err= err.message)) return raise ContainerUnsupportedError("No idea how to add objects to containers of type {typ}".format(typ= container.TypeId))
def getContainer(feat): feat = screen(feat) cnt = None for dep in feat.InList: if isContainer(dep): if feat in getDirectChildren(dep): if cnt is not None and dep is not cnt: raise ContainerTreeError("Container tree is not a tree") cnt = dep if cnt is None: return feat.Document return screen(cnt)
def getContainer(feat): feat = screen(feat) cnt = None for dep in feat.InList: if isContainer(dep): if feat in getDirectChildren(dep): if cnt is not None and dep is not cnt: raise ContainerTreeError("Container tree is not a tree") cnt = dep if cnt is None: return feat.Document return screen(cnt)
def getContainerChain(feat): '''getContainerChain(feat): return a list of containers feat is in. Last container directly contains the feature. Example of output: [<document>,<SuperPart>,<Part>,<Body>]''' if feat.isDerivedFrom('App::Document'): return [] list_traversing_now = [feat] set_of_deps = set() list_of_deps = [] while len(list_traversing_now) > 0: list_to_be_traversed_next = [] for feat in list_traversing_now: for dep in feat.InList: if isContainer(dep) and feat in getDirectChildren(dep): if not (dep in set_of_deps): set_of_deps.add(dep) list_of_deps.append(screen(dep)) list_to_be_traversed_next.append(dep) if len(list_to_be_traversed_next) > 1: raise ContainerTreeError("Container tree is not a tree") list_traversing_now = list_to_be_traversed_next return [feat.Document] + list_of_deps[::-1]
def execute(self, selfobj): from PartOMagic.Gui.Utils import screen if selfobj.Tip is not None: selfobj.Shape = transformCopy_Smart( screen(selfobj.Tip).Shape, selfobj.Placement) else: selfobj.Shape = Part.Shape()
def setActiveContainer(cnt): '''setActiveContainer(cnt): sets active container. To set no active container, supply ActiveDocument. None is not accepted.''' cnt = screen(cnt) import FreeCAD as App import FreeCADGui as Gui if hasattr(App, "ActiveContainer"): App.setActiveContainer(cnt) return if not isContainer(cnt): raise NotAContainerError("Can't make '{feat}' active as container, because it's not a container (or an unknown type of container)." .format(feat= cnt.Label)) if cnt.isDerivedFrom("Part::BodyBase"): Gui.ActiveDocument.ActiveView.setActiveObject("pdbody", cnt) part = None else: part = cnt Gui.ActiveDocument.ActiveView.setActiveObject("pdbody", None) if part: if part.isDerivedFrom("App::Document"): part = None Gui.ActiveDocument.ActiveView.setActiveObject("part", part)
def setActiveContainer(cnt): '''setActiveContainer(cnt): sets active container. To set no active container, supply ActiveDocument. None is not accepted.''' cnt = screen(cnt) import FreeCAD as App import FreeCADGui as Gui if hasattr(App, "ActiveContainer"): App.setActiveContainer(cnt) return if not isContainer(cnt): raise NotAContainerError( "Can't make '{feat}' active as container, because it's not a container (or an unknown type of container)." .format(feat=cnt.Label)) if cnt.isDerivedFrom("Part::BodyBase"): Gui.ActiveDocument.ActiveView.setActiveObject("pdbody", cnt) part = None else: part = cnt Gui.ActiveDocument.ActiveView.setActiveObject("pdbody", None) if part: if part.isDerivedFrom("App::Document"): part = None Gui.ActiveDocument.ActiveView.setActiveObject("part", part)
def getContainerChain(feat): '''getContainerChain(feat): return a list of containers feat is in. Last container directly contains the feature. Example of output: [<document>,<SuperPart>,<Part>,<Body>]''' if feat.isDerivedFrom('App::Document'): return [] list_traversing_now = [feat] set_of_deps = set() list_of_deps = [] while len(list_traversing_now) > 0: list_to_be_traversed_next = [] for feat in list_traversing_now: for dep in feat.InList: if isContainer(dep) and feat in getDirectChildren(dep): if not (dep in set_of_deps): set_of_deps.add(dep) list_of_deps.append(screen(dep)) list_to_be_traversed_next.append(dep) if len(list_to_be_traversed_next) > 1: raise ContainerTreeError("Container tree is not a tree") list_traversing_now = list_to_be_traversed_next return [feat.Document] + list_of_deps[::-1]
def getDirectChildren(container): container = screen(container) if not isContainer(container): raise NotAContainerError( "getDirectChildren: supplied object is not a container. It must be a container." ) if container.isDerivedFrom("App::Document"): # find all objects not contained by any Part or Body result = set(container.Objects) for obj in container.Objects: if isContainer(obj): children = set(getDirectChildren(obj)) result = result - children return result elif container.hasExtension("App::GroupExtension"): result = container.Group if container.hasExtension("App::OriginGroupExtension"): if container.Origin is not None: result.append(container.Origin) return result elif container.isDerivedFrom("App::Origin"): return container.OriginFeatures raise ContainerUnsupportedError( "getDirectChildren: unexpected container type!")
def RunOrTest(self, b_run): if Gui.ActiveDocument: in_edit = Gui.ActiveDocument.getInEdit() if in_edit is not None: raise CommandError( self, u"{object} is currently being edited. Can't enter anything." .format(object=in_edit.Object.Label)) sel = Gui.Selection.getSelection() if len(sel) == 0: raise CommandError( self, "Enter Object command. Please select an object to enter, first. It can be a container, or a sketch." ) elif len(sel) == 1: sel = screen(sel[0]) ac = Containers.activeContainer() if Containers.isContainer(sel): if sel in Containers.getContainerChain(ac) + [ac]: raise CommandError(self, "Already inside this object") if b_run: Containers.setActiveContainer(sel) if b_run: Gui.Selection.clearSelection() else: cnt = Containers.getContainer(sel) if ac is cnt: if b_run: Gui.ActiveDocument.setEdit(sel) else: if b_run: Containers.setActiveContainer(cnt) else: raise CommandError( self, u"Enter Object command. You need to select exactly one object (you selected {num})." .format(num=len(sel)))
def isMovableContainer(obj): '''isMovableContainer(obj): reuturns if obj is a movable container, that forms a local coordinate system.''' obj = screen(obj) if obj.isDerivedFrom('App::Document'): return False if obj.hasExtension('App::OriginGroupExtension'): return True return False
def isMovableContainer(obj): '''isMovableContainer(obj): reuturns if obj is a movable container, that forms a local coordinate system.''' obj = screen(obj) if obj.isDerivedFrom('App::Document'): return False if obj.hasExtension('App::OriginGroupExtension'): return True return False
def addObjectTo(container, feature, b_advance_tip=True): container = screen(container) feature = screen(feature) cnt_old = getContainer(feature) if not cnt_old.isDerivedFrom('App::Document') and cnt_old is not container: raise AlreadyInContainerError( u"Object '{obj}' is already in '{cnt_old}'. Cannot add it to '{cnt_new}'" .format(obj=feature.Label, cnt_old=cnt_old.Label, cnt_new=container.Label)) if cnt_old is container: return #nothing to do if feature is container: raise ContainerError( u"Attempting to add {feat} to itself. Feature can't contain itself." .format(feat=feature.Label)) if container.hasExtension("App::GroupExtension"): #container.addObject(feature) container.Group = container.Group + [feature] if b_advance_tip: try: container.Proxy.advanceTip(container, feature) except AttributeError: pass except Exception as err: App.Console.printError( u"Tip advancement routine failed with an error when adding {feat} to {cnt}. {err}" .format(feat=feature.Label, cnt=container.Label, err=err.message)) return raise ContainerUnsupportedError( "No idea how to add objects to containers of type {typ}".format( typ=container.TypeId))
def advanceTip(self, selfobj, new_object): from PartOMagic.Gui.Utils import screen old_tip = screen(selfobj.Tip) new_tip = old_tip if old_tip is None: new_tip = new_object if old_tip in new_object.OutList: new_tip = new_object if new_tip is None: return if new_tip is old_tip: return if new_tip.Name.startswith("Clone"): return if new_tip.Name.startswith("ShapeBinder"): return selfobj.Tip = new_tip
def advanceTip(self, selfobj, new_object): print("advanceTip") from PartOMagic.Gui.Utils import screen old_tip = screen(selfobj.Tip) new_tip = old_tip if old_tip is None: new_tip = new_object if old_tip in new_object.OutList: new_tip = new_object if new_tip is None: return if new_tip is old_tip: return if new_tip.Name.startswith("Clone"): return if new_tip.Name.startswith("ShapeBinder"): return selfobj.Tip = new_tip
def isContainer(obj): '''isContainer(obj): returns True if obj is an object container, such as Group, Part, Body. The important characterisic of an object being a container is that it can be activated to receive new objects. Documents are considered containers, too.''' obj = screen(obj) if obj.isDerivedFrom('App::Document'): return True if obj.hasExtension('App::GeoFeatureGroupExtension'): return True # if obj.hasExtension('App::GroupExtension'): # return True # experimental... if obj.isDerivedFrom('App::Origin'): return True return False
def isContainer(obj): '''isContainer(obj): returns True if obj is an object container, such as Group, Part, Body. The important characterisic of an object being a container is that it can be activated to receive new objects. Documents are considered containers, too.''' obj = screen(obj) if obj.isDerivedFrom('App::Document'): return True if obj.hasExtension('App::GeoFeatureGroupExtension'): return True # if obj.hasExtension('App::GroupExtension'): # return True # experimental... if obj.isDerivedFrom('App::Origin'): return True return False
def getDirectChildren(container): container = screen(container) if not isContainer(container): raise NotAContainerError("getDirectChildren: supplied object is not a contianer. It must be a container.") if container.isDerivedFrom("App::Document"): # find all objects not contained by any Part or Body result = set(container.Objects) for obj in container.Objects: if isContainer(obj): children = set(getDirectChildren(obj)) result = result - children return result elif container.hasExtension("App::GroupExtension"): result = container.Group if container.hasExtension("App::OriginGroupExtension"): if container.Origin is not None: result.append(container.Origin) return result elif container.isDerivedFrom("App::Origin"): return container.OriginFeatures raise ContainerUnsupportedError("getDirectChildren: unexpected container type!")
def RunOrTest(self, b_run): if Gui.ActiveDocument: in_edit = Gui.ActiveDocument.getInEdit() if in_edit is not None: raise CommandError(self, u"{object} is currently being edited. Can't enter anything.".format(object= in_edit.Object.Label)) sel = Gui.Selection.getSelection() if len(sel)==0 : raise CommandError(self, "Enter Object command. Please select an object to enter, first. It can be a container, or a sketch.") elif len(sel)==1: sel = screen(sel[0]) ac = Containers.activeContainer() if Containers.isContainer(sel): if sel in Containers.getContainerChain(ac) + [ac]: raise CommandError(self, "Already inside this object") if b_run: Containers.setActiveContainer(sel) if b_run: Gui.Selection.clearSelection() else: cnt = Containers.getContainer(sel) if ac is cnt: if b_run: Gui.ActiveDocument.setEdit(sel) else: if b_run: Containers.setActiveContainer(cnt) else: raise CommandError(self, u"Enter Object command. You need to select exactly one object (you selected {num}).".format(num= len(sel)))
def getAllDependent(feat): '''getAllDependent(feat): gets all features that depend on feat, directly or indirectly. Returns a list, with deepest dependencies last. feat is not included in the list, except if the feature depends on itself (dependency loop).''' if feat.isDerivedFrom("App::Document"): return [] list_traversing_now = [feat] set_of_deps = set() list_of_deps = [] while len(list_traversing_now) > 0: list_to_be_traversed_next = [] for feat in list_traversing_now: for dep in feat.InList: if not (dep in set_of_deps): set_of_deps.add(dep) list_of_deps.append(screen(dep)) list_to_be_traversed_next.append(dep) list_traversing_now = list_to_be_traversed_next return list_of_deps
def getAllDependent(feat): '''getAllDependent(feat): gets all features that depend on feat, directly or indirectly. Returns a list, with deepest dependencies last. feat is not included in the list, except if the feature depends on itself (dependency loop).''' if feat.isDerivedFrom("App::Document"): return [] list_traversing_now = [feat] set_of_deps = set() list_of_deps = [] while len(list_traversing_now) > 0: list_to_be_traversed_next = [] for feat in list_traversing_now: for dep in feat.InList: if not (dep in set_of_deps): set_of_deps.add(dep) list_of_deps.append(screen(dep)) list_to_be_traversed_next.append(dep) list_traversing_now = list_to_be_traversed_next return list_of_deps
def execute(self,selfobj): from PartOMagic.Gui.Utils import screen if selfobj.Tip is not None: selfobj.Shape = transformCopy_Smart(screen(selfobj.Tip).Shape, selfobj.Placement) else: selfobj.Shape = Part.Shape()