예제 #1
0
 def RunOrTest(self, b_run):
     # outline.
     # 0. user click calls Activated().
     # 1. set up self.waiter, which waits for new object to be created
     # 2. waiter calls Activated() of this command, and knows what object was created
     # 3. command removes waiter, and calls morphContainer
     
     if self.waiter is not None:
         if self.waiter.is_done:
             waiter = self.waiter
             self.waiter = None
             assert(b_run)
             #enforce PoM observer to put feature into appropriate container
             from PartOMagic.Gui import Observer as pomObserver
             if pomObserver.isRunning():
                 pomObserver.observerInstance.poll()
                 
             #check
             if not Containers.isContainer(waiter.target_container): 
                 raise CommandError(self, u"You created {obj}, which isn't a container. Can't morph {src} into {objt}. Morphing canceled."
                                           .format(obj= waiter.target_container, 
                                                   objt= waiter.target_container,
                                                   src= waiter.source_container))
             #make sure active container is not being messed with...
             ac = Containers.activeContainer()
             if waiter.source_container in Containers.getContainerChain(ac)+[ac]:
                 pomObserver.activateContainer(Containers.getContainer(waiter.source_container))
             if waiter.target_container in Containers.getContainerChain(ac)+[ac]:
                 pomObserver.activateContainer(Containers.getContainer(waiter.target_container))
             
             # do it!
             with Transaction("Morph container"):
                 morphContainer(waiter.source_container, waiter.target_container)
             return
         else:
             raise CommandError(self, "(waiting for new container to be created...)")
     sel = Gui.Selection.getSelection()
     if len(sel)==0 :
         raise CommandError(self, self.GetResources()['ToolTip'])
     elif len(sel)==1:
         sel = sel[0]
         if not Containers.isContainer(sel):
             raise CommandError(self, "Selected object is not a container")
         ac = Containers.activeContainer()
         if sel in Containers.getContainerChain(ac)+[ac]:
             raise CommandError(self, "Deactivate the container to be morphed first, please.")
         if b_run: self.waiter = WaitForNewContainer(self, sel)
         if b_run: Gui.Selection.clearSelection()
     else:
         raise CommandError(self, u"You need to select exactly one object (you selected {num}), ad it must be a container.".format(num= len(sel)))
예제 #2
0
 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)))
예제 #3
0
def compoundFromAssembly(root, flatten, exclude, recursive = True, visit_set = None):
    if visit_set is None:
        visit_set = set()
    
    #recursion guard
    if root in visit_set:
        raise ValueError("Circular dependency")
    visit_set.add(root)
    
    if hasattr(root, 'Shape'):
        return root.Shape
    else:
        children = Containers.getDirectChildren(root)
        shapes = []
        for child in children:
            if child in exclude:
                continue
            if child.isDerivedFrom('App::Origin'):
                continue #otherwise, origins create empty compounds - undesirable.
            if hasattr(child, 'Shape'):
                shapes.append(child.Shape)
            elif Containers.isContainer(child) and recursive:
                cmp = compoundFromAssembly(child, flatten, exclude, recursive, visit_set)
                if flatten:
                    shapes.extend(cmp.childShapes())
                else:
                    shapes.append(cmp)
        transform = root.Placement if hasattr(root, 'Placement') else None
        ret = Part.makeCompound(shapes)
        if transform is not None:
            ret.Placement = transform
        return ret
예제 #4
0
 def slotChangedObject(self, feature, prop_name):
     if prop_name == 'Group':
         if not Containers.isContainer(feature):
             return
         if 'Restore' in feature.State:
             return
         if App.GuiUp:
             global oneshot
             if oneshot is None or oneshot.is_done:
                 oneshot = DelayedExecute(
                     (lambda doc=feature.Document: updateAllGhosts(doc)),
                     delay=100)
         else:
             updateAllGhosts(feature.Document)
     elif prop_name == 'Placement':
         if not Containers.isContainer(feature):
             return
         if 'Restore' in feature.State:
             return
         onContainerPlacementChanged(feature)
예제 #5
0
 def trackExpands(self):
     docname = App.ActiveDocument.Name
     for obj in App.ActiveDocument.Objects:
         objname = obj.Name
         key = (docname, objname)
         curstate = 'Expanded' in obj.State
         oldstate = self.expandedness.get(key, False)
         if curstate != oldstate:
             self.expandedness[key] = curstate
             if GT.isContainer(obj):
                 gc = GenericContainer(obj)
                 gc.ViewObject.call(gc.ViewObject.expandednessChanged, oldstate, curstate)
예제 #6
0
 def trackExpands(self):
     docname = App.ActiveDocument.Name
     for obj in App.ActiveDocument.Objects:
         objname = obj.Name
         key = (docname, objname)
         curstate = 'Expanded' in obj.State
         oldstate = self.expandedness.get(key, False)
         if curstate != oldstate:
             self.expandedness[key] = curstate
             if GT.isContainer(obj):
                 gc = GenericContainer(obj)
                 gc.ViewObject.call(gc.ViewObject.expandednessChanged, oldstate, curstate)
예제 #7
0
 def RunOrTest(self, b_run):
     sel = Gui.Selection.getSelection()
     if len(sel)==0 :
         raise CommandError(self,"No object selected. Please select something, first.")
     else:
         if b_run: 
             new_sel = []
             for obj in sel:
                 if Containers.isContainer(obj):
                     new_sel.extend(Containers.getDirectChildren(obj))
                 else:
                     new_sel.extend(obj.ViewObject.claimChildren())
             select(new_sel)
예제 #8
0
 def RunOrTest(self, b_run):
     sel = Gui.Selection.getSelection()
     if len(sel) == 0:
         raise CommandError(
             self, "No object selected. Please select something, first.")
     else:
         if b_run:
             new_sel = []
             for obj in sel:
                 if Containers.isContainer(obj):
                     new_sel.extend(Containers.getDirectChildren(obj))
                 else:
                     new_sel.extend(obj.ViewObject.claimChildren())
             select(new_sel)
예제 #9
0
def compoundFromAssembly(root,
                         flatten,
                         exclude,
                         recursive=True,
                         visit_set=None):
    if visit_set is None:
        visit_set = set()

    #recursion guard
    if root in visit_set:
        raise ValueError("Circular dependency")
    visit_set.add(root)

    if has_property(root, 'Shape'):
        return root.Shape
    else:
        children = Containers.getDirectChildren(root)
        shapes = []
        for child in children:
            if child in exclude:
                continue
            if child.isDerivedFrom('App::Origin'):
                continue  #otherwise, origins create empty compounds - undesirable.
            if has_property(
                    child, 'Shape'
            ):  #since realthunder, Part has Shape attribute, but not Shape property. We want to process Parts ourselves.
                if not child.Shape.isNull():
                    shapes.append(child.Shape)
            elif Containers.isContainer(child) and recursive:
                cmp = compoundFromAssembly(child, flatten, exclude, recursive,
                                           visit_set)
                if flatten:
                    shapes.extend(cmp.childShapes())
                else:
                    shapes.append(cmp)
            elif hasattr(
                    obj, 'Shape'
            ):  #App::Link may have attribute but not property, and we totally want to include it.
                if not child.Shape.isNull():
                    shapes.append(child.Shape)
        transform = root.Placement if hasattr(root, 'Placement') else None
        ret = Part.makeCompound(shapes)
        if transform is not None:
            ret.Placement = transform
        return ret
예제 #10
0
def compoundFromAssembly(root,
                         flatten,
                         exclude,
                         recursive=True,
                         visit_set=None):
    if visit_set is None:
        visit_set = set()

    #recursion guard
    if root in visit_set:
        raise ValueError("Circular dependency")
    visit_set.add(root)

    if hasattr(root, 'Shape'):
        return root.Shape
    else:
        children = Containers.getDirectChildren(root)
        shapes = []
        for child in children:
            if child in exclude:
                continue
            if child.isDerivedFrom('App::Origin'):
                continue  #otherwise, origins create empty compounds - undesirable.
            if hasattr(child, 'Shape'):
                shapes.append(child.Shape)
            elif Containers.isContainer(child) and recursive:
                cmp = compoundFromAssembly(child, flatten, exclude, recursive,
                                           visit_set)
                if flatten:
                    shapes.extend(cmp.childShapes())
                else:
                    shapes.append(cmp)
        transform = root.Placement if hasattr(root, 'Placement') else None
        ret = Part.makeCompound(shapes)
        if transform is not None:
            ret.Placement = transform
        return ret
예제 #11
0
 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)))            
예제 #12
0
def morphContainer(src_container, dst_container):
    if not Containers.isContainer(src_container):
        raise TypeError(u"{obj} is not a container".format(obj= src_container.Label))
    if not Containers.isContainer(dst_container):
        raise TypeError(u"{obj} is not a container".format(obj= dst_container.Label))
    if src_container in Containers.getContainerChain(dst_container):
        raise Containers.ContainerTreeError(u"Cannot morph {src} into {dst}, because {src} contains {dst}"
                                            .format(src= src_container.Label, dst= dst_container.Label))
    
    doc = dst_container.Document

    #origin...
    if hasattr(src_container, "Origin") and hasattr(dst_container, "Origin"):
        if dst_container.Origin is not None: 
            doc.removeObject(dst_container.Origin.Name)
        dst_container.Origin = src_container.Origin; src_container.Origin = None
    
    #content
    assert(len(dst_container.Group) == 0)
    g = src_container.Group
    src_container.Group = [] #withdraw first, add last - otherwise, error is thrown
    dst_container.Group = g 
    if hasattr(dst_container, 'Origin'):
        if hasattr(dst_container, 'Proxy') and dst_container.Origin is not None:
            #workaround for origin not being claimed as child on Py-powered containers
            dst_container.Group = [dst_container.Origin] + dst_container.Group 
        elif dst_container.Origin is not None and dst_container.Origin in dst_container.Group:
            #if converting Py cotainer into c++-one, undo the workaround
            content = dst_container.Group 
            content.remove(dst_container.Origin)
    
    #Tip
    if hasattr(src_container, "Tip") and hasattr(dst_container, "Tip"):
        tip_list = src_container.Tip
        if type(tip_list) is not list:
            tip_list = [tip_list] if tip_list is not None else []
        if type(dst_container.Tip) is list:
            dst_container.Tip = tip_list
        else:
            if len(tip_list) == 0:
                dst_container.Tip = None
            elif len(tip_list) == 1:
                dst_container.Tip = tip_list[0]
            else:
                App.Console.PrintWarning(u"Target Tip can only point to one object. Source Tip points to {num}. Last object from source tip was taken.\n"
                                         .format(num= len(tip_list)))
                dst_container.Tip = tip_list[-1]
    
    #other properties...
    
    properties_to_avoid = set([
        # these are avoided because they need manual treatment...
        'Group',
        'Origin',
        'ExpressionEngine',
        'Tip',
        'Label',
        #.. and these should never be copied at all
        'ExtensionProxy',
        'Proxy',
    ])
    
    properties_to_copy = []
    for prop in src_container.PropertiesList:
        if len(src_container.getEditorMode(prop)) == 0: # screen out read-only and hidden properties
            if not prop in properties_to_avoid:
                properties_to_copy.append(prop)
    
    print("copying properties")
    for prop in properties_to_copy:
        print("  "+prop)
        copyProperty(src_container, dst_container, prop)
        
    #Copy expressions
    for expr in src_container.ExpressionEngine:
        dst_container.setExpression(*expr)
        
    #redirect links
    substituteObjectInProperties(src_container, dst_container, doc.Objects)
    substituteObjectInExpressions(src_container, dst_container, doc.Objects)
    substituteObjectInSpreadsheets(src_container, dst_container, doc.Objects)
    
    label = src_container.Label
    label = label.replace(src_container.Name, dst_container.Name)
    
    Containers.withdrawObject(src_container)
    doc.removeObject(src_container.Name)
    
    #copy Label last, because otherwise it gets "001" at the end...
    dst_container.Label = label
예제 #13
0
def morphContainer(src_container, dst_container):
    if not Containers.isContainer(src_container):
        raise TypeError(
            u"{obj} is not a container".format(obj=src_container.Label))
    if not Containers.isContainer(dst_container):
        raise TypeError(
            u"{obj} is not a container".format(obj=dst_container.Label))
    if src_container in Containers.getContainerChain(dst_container):
        raise Containers.ContainerTreeError(
            u"Cannot morph {src} into {dst}, because {src} contains {dst}".
            format(src=src_container.Label, dst=dst_container.Label))

    doc = dst_container.Document

    #origin...
    if hasattr(src_container, "Origin") and hasattr(dst_container, "Origin"):
        if dst_container.Origin is not None:
            doc.removeObject(dst_container.Origin.Name)
        dst_container.Origin = src_container.Origin
        src_container.Origin = None

    #content
    assert (len(dst_container.Group) == 0)
    g = src_container.Group
    src_container.Group = [
    ]  #withdraw first, add last - otherwise, error is thrown
    dst_container.Group = g
    if hasattr(dst_container, 'Origin'):
        if hasattr(dst_container,
                   'Proxy') and dst_container.Origin is not None:
            #workaround for origin not being claimed as child on Py-powered containers
            dst_container.Group = [dst_container.Origin] + dst_container.Group
        elif dst_container.Origin is not None and dst_container.Origin in dst_container.Group:
            #if converting Py cotainer into c++-one, undo the workaround
            content = dst_container.Group
            content.remove(dst_container.Origin)

    #Tip
    if hasattr(src_container, "Tip") and hasattr(dst_container, "Tip"):
        tip_list = src_container.Tip
        if type(tip_list) is not list:
            tip_list = [tip_list] if tip_list is not None else []
        if type(dst_container.Tip) is list:
            dst_container.Tip = tip_list
        else:
            if len(tip_list) == 0:
                dst_container.Tip = None
            elif len(tip_list) == 1:
                dst_container.Tip = tip_list[0]
            else:
                App.Console.PrintWarning(
                    u"Target Tip can only point to one object. Source Tip points to {num}. Last object from source tip was taken.\n"
                    .format(num=len(tip_list)))
                dst_container.Tip = tip_list[-1]

    #other properties...

    properties_to_avoid = set([
        # these are avoided because they need manual treatment...
        'Group',
        'Origin',
        'ExpressionEngine',
        'Tip',
        'Label',
        #.. and these should never be copied at all
        'ExtensionProxy',
        'Proxy',
    ])

    properties_to_copy = []
    for prop in src_container.PropertiesList:
        if len(src_container.getEditorMode(
                prop)) == 0:  # screen out read-only and hidden properties
            if not prop in properties_to_avoid:
                properties_to_copy.append(prop)

    print("copying properties")
    for prop in properties_to_copy:
        print("  " + prop)
        copyProperty(src_container, dst_container, prop)

    #Copy expressions
    for expr in src_container.ExpressionEngine:
        dst_container.setExpression(*expr)

    #redirect links
    substituteObjectInProperties(src_container, dst_container, doc.Objects)
    substituteObjectInExpressions(src_container, dst_container, doc.Objects)
    substituteObjectInSpreadsheets(src_container, dst_container, doc.Objects)

    label = src_container.Label
    label = label.replace(src_container.Name, dst_container.Name)

    Containers.withdrawObject(src_container)
    doc.removeObject(src_container.Name)

    #copy Label last, because otherwise it gets "001" at the end...
    dst_container.Label = label
예제 #14
0
    def RunOrTest(self, b_run):
        # outline.
        # 0. user click calls Activated().
        # 1. set up self.waiter, which waits for new object to be created
        # 2. waiter calls Activated() of this command, and knows what object was created
        # 3. command removes waiter, and calls morphContainer

        if self.waiter is not None:
            if self.waiter.is_done:
                waiter = self.waiter
                self.waiter = None
                assert (b_run)
                #enforce PoM observer to put feature into appropriate container
                from PartOMagic.Gui import Observer as pomObserver
                if pomObserver.isRunning():
                    pomObserver.observerInstance.poll()

                #check
                if not Containers.isContainer(waiter.target_container):
                    raise CommandError(
                        self,
                        u"You created {obj}, which isn't a container. Can't morph {src} into {objt}. Morphing canceled."
                        .format(obj=waiter.target_container,
                                objt=waiter.target_container,
                                src=waiter.source_container))
                #make sure active container is not being messed with...
                ac = Containers.activeContainer()
                if waiter.source_container in Containers.getContainerChain(
                        ac) + [ac]:
                    pomObserver.activateContainer(
                        Containers.getContainer(waiter.source_container))
                if waiter.target_container in Containers.getContainerChain(
                        ac) + [ac]:
                    pomObserver.activateContainer(
                        Containers.getContainer(waiter.target_container))

                # do it!
                with Transaction("Morph container"):
                    morphContainer(waiter.source_container,
                                   waiter.target_container)
                return
            else:
                raise CommandError(
                    self, "(waiting for new container to be created...)")
        sel = Gui.Selection.getSelection()
        if len(sel) == 0:
            raise CommandError(self, self.GetResources()['ToolTip'])
        elif len(sel) == 1:
            sel = sel[0]
            if not Containers.isContainer(sel):
                raise CommandError(self, "Selected object is not a container")
            ac = Containers.activeContainer()
            if sel in Containers.getContainerChain(ac) + [ac]:
                raise CommandError(
                    self,
                    "Deactivate the container to be morphed first, please.")
            if b_run: self.waiter = WaitForNewContainer(self, sel)
            if b_run: Gui.Selection.clearSelection()
        else:
            raise CommandError(
                self,
                u"You need to select exactly one object (you selected {num}), ad it must be a container."
                .format(num=len(sel)))