コード例 #1
0
 def clicked(self, button):
     if button == QtGui.QDialogButtonBox.Ignore:
         # ask for confirmation before resetting everything
         msgName = Asm4.nameLabel(self.selectedLink)
         # see whether the ExpressionEngine field is filled
         if self.selectedLink.ExpressionEngine:
             # if yes, then ask for confirmation
             confirmed = Asm4.confirmBox(
                 'This command will release all attachments on ' + msgName +
                 ' and set it to manual positioning in its current location.'
             )
             # if not, then it's useless to bother the user
         else:
             confirmed = True
         if confirmed:
             # unset the ExpressionEngine for the Placement
             self.selectedLink.setExpression('Placement', None)
             # reset the assembly properties
             Asm4.makeAsmProperties(self.selectedLink, reset=True)
             # finish
             FCC.PrintWarning("Part is now manually placed\n")
             self.finish()
         else:
             FCC.PrintWarning("Part untouched\n")
             self.finish()
コード例 #2
0
    def Apply( self ):
        # get the instance to attach to:
        # it's either the top level assembly or a sister App::Link
        if self.parentList.currentText() == 'Parent Assembly':
            a_Link = 'Parent Assembly'
            a_Part = None
        elif self.parentList.currentIndex() > 1:
            parent = self.parentTable[ self.parentList.currentIndex() ]
            a_Link = parent.Name
            a_Part = parent.LinkedObject.Document.Name
        else:
            a_Link = None
            a_Part = None

        # the attachment LCS's name in the parent
        # check that something is selected in the QlistWidget
        if self.attLCSlist.selectedItems():
            a_LCS = self.attLCStable[ self.attLCSlist.currentRow() ].Name
        else:
            a_LCS = None

        # the linked App::Part's name
        l_Part = self.selectedLink.LinkedObject.Document.Name

        # the LCS's name in the linked part to be used for its attachment
        # check that something is selected in the QlistWidget
        if self.partLCSlist.selectedItems():
            #l_LCS = self.partLCSlist.selectedItems()[0].text()
            l_LCS = self.partLCStable[ self.partLCSlist.currentRow() ].Name
        else:
            l_LCS = None

        # check that all of them have something in
        # constrName has been checked at the beginning
        if a_Link and a_LCS and l_Part and l_LCS :
            # this is where all the magic is, see:
            # 
            # https://forum.freecadweb.org/viewtopic.php?p=278124#p278124
            #
            # as of FreeCAD v0.19 the syntax is different:
            # https://forum.freecadweb.org/viewtopic.php?f=17&t=38974&p=337784#p337784
            #
            # expr = ParentLink.Placement * ParentPart#LCS.Placement * constr_LinkName.AttachmentOffset * LinkedPart#LCS.Placement ^ -1'			
            # expr = LCS_in_the_assembly.Placement * constr_LinkName.AttachmentOffset * LinkedPart#LCS.Placement ^ -1'			
            expr = Asm4.makeExpressionPart( a_Link, a_Part, a_LCS, l_Part, l_LCS )
            # add the Asm4 properties if it's a pure App::Link
            Asm4.makeAsmProperties(self.selectedLink)
            # store the part where we're attached to in the constraints object
            self.selectedLink.AssemblyType = 'Asm4EE'
            self.selectedLink.AttachedBy = '#'+l_LCS
            self.selectedLink.AttachedTo = a_Link+'#'+a_LCS
            # load the expression into the link's Expression Engine
            self.selectedLink.setExpression('Placement', expr )
            # recompute the object to apply the placement:
            self.selectedLink.recompute()
            self.parentAssembly.recompute(True)
            return True
        else:
            #FCC.PrintWarning("Problem in selections\n")
            return False
コード例 #3
0
 def freeInsert(self):
     # ask for confirmation before resetting everything
     fName  = self.selectedFastener.Name
     fLabel = self.selectedFastener.Label
     if fName==fName:
         fText = fName
     else:
         fText = fName+' ('+fName+')'
     # see whether the ExpressionEngine field is filled
     if self.old_EE :
         # if yes, then ask for confirmation
         confirmed = Asm4.confirmBox('This command will release all attachments on '+fText+' and set it to manual positioning in its current location.')
         # if not, then it's useless to bother the user
     else:
         confirmed = True
     if confirmed:
         # unset the ExpressionEngine for the Placement
         # self.selectedFastener.setExpression( 'Placement', expr )
         self.selectedFastener.setExpression('Placement', None)
         # reset the assembly properties
         Asm4.makeAsmProperties(self.selectedFastener)
         # finish
         self.close()
     else:
         return
コード例 #4
0
    def onApply(self):
        # get the name of the part to attach to:
        # it's either the top level part name ('Model')
        # or the provided link's name.

        if self.parentList.currentText() == 'Parent Assembly':
            a_Link = 'Parent Assembly'
            a_Part = None
        elif self.parentList.currentIndex() > 1:
            parent = self.asmParts[ self.parentList.currentIndex() ]
            a_Link = parent.Name
            a_Part = parent.LinkedObject.Document.Name
        else:
            a_Link = None
            a_Part = None

        # the attachment LCS's name in the parent
        # check that something is selected in the QlistWidget
        if self.attLCSlist.selectedItems():
            a_LCS = self.attLCStable[ self.attLCSlist.currentRow() ].Name
        else:
            a_LCS = None

        # check that all of them have something in
        if a_Link and a_LCS :
            # <<LinkName>>.Placement.multiply( <<LinkName>>.<<LCS.>>.Placement )
            # expr = '<<'+ a_Part +'>>.Placement.multiply( <<'+ a_Part +'>>.<<'+ a_LCS +'.>>.Placement )'
            expr = self.makeExpressionFastener( a_Link, a_Part, a_LCS )
            # this can be skipped when this method becomes stable
            self.expression.setText( expr )
            # indicate the this fastener has been placed with the Assembly4 workbench
            if not hasattr(self.selectedFastener,'AssemblyType'):
                Asm4.makeAsmProperties(self.selectedFastener)
            self.selectedFastener.AssemblyType = 'Asm4EE'
            # the fastener is attached by its Origin, no extra LCS
            self.selectedFastener.AttachedBy = 'Origin'
            # store the part where we're attached to in the constraints object
            self.selectedFastener.AttachedTo = a_Link+'#'+a_LCS
            # load the built expression into the Expression field of the constraint
            self.selectedFastener.setExpression( 'Placement', expr )
            # check the Invert and Offset values
            self.selectedFastener.invert = self.Invert.isChecked()
            self.selectedFastener.offset = self.Offset.value()
            # recompute the object to apply the placement:
            self.selectedFastener.recompute()
            self.parentAssembly.recompute()
            self.activeDoc.recompute()
            # highlight the selected fastener in its new position
            Gui.Selection.clearSelection()
            Gui.Selection.addSelection( self.activeDoc.Name, 'Model', self.selectedFastener.Name +'.')
        else:
            self.expression.setText( 'Problem in selections' )
        return
コード例 #5
0
 def freeInsert(self):
     # ask for confirmation before resetting everything
     linkName = self.selectedLink.Name
     linkLabel = self.selectedLink.Label
     if linkName == linkName:
         linkText = linkName
     else:
         linkText = linkName + ' (' + linkName + ')'
     # see whether the ExpressionEngine field is filled
     if self.selectedLink.ExpressionEngine:
         # if yes, then ask for confirmation
         confirmed = Asm4.confirmBox(
             'This command will release all attachments on ' + linkText +
             ' and set it to manual positioning in its current location.')
         # if not, then it's useless to bother the user
     else:
         confirmed = True
     if confirmed:
         # unset the ExpressionEngine for the Placement
         self.selectedLink.setExpression('Placement', None)
         # reset the assembly properties
         Asm4.makeAsmProperties(self.selectedLink, reset=True)
         """
         # property AssemblyType
         if hasattr(self.selectedLink,'AssemblyType'):
             self.selectedLink.AssemblyType = ''
         else:
             self.selectedLink.addProperty( 'App::PropertyString', 'AssemblyType', 'Attachment' ).AssemblyType = ''
         # property AttachedBy
         if hasattr(self.selectedLink,'AttachedBy'):
             self.selectedLink.AttachedBy = ''
         else:
             self.selectedLink.addProperty( 'App::PropertyString', 'AttachedBy', 'Attachment' ).AttachedBy = ''
         # property AttachedTo
         if hasattr(self.selectedLink,'AttachedTo'):
             self.selectedLink.AttachedTo = ''
         else:
             self.selectedLink.addProperty( 'App::PropertyString', 'AttachedTo', 'Attachment' ).AttachedTo = ''
         # property AttachmentOffset
         if hasattr(self.selectedLink,'AttachmentOffset'):
             self.selectedLink.AttachmentOffset = App.Placement()
         else:
             self.selectedLink.addProperty( 'App::PropertyPlacement', 'AttachmentOffset', 'Attachment' ).AttachmentOffset = App.Placement()
         """
         Gui.Selection.clearSelection()
         Gui.Selection.addSelection(self.activeDoc.Name, 'Model',
                                    self.selectedLink.Name + '.')
         # finish
         self.close()
     else:
         return
コード例 #6
0
 def clicked(self, bt):
     if bt == QtGui.QDialogButtonBox.Ignore:
         # ask for confirmation before resetting everything
         msgName = Asm4.nameLabel(self.selectedFastener)
         # see whether the ExpressionEngine field is filled
         if self.old_EE :
             # if yes, then ask for confirmation
             confirmed = Asm4.confirmBox('This command will release all attachments on '+msgName+' and set it to manual positioning in its current location.')
         else:
             # if not, then it's useless to bother the user
             confirmed = True
         if confirmed:
             # unset the ExpressionEngine in the Placement
             self.selectedFastener.setExpression('Placement', None)
             # reset Asm4 properties
             Asm4.makeAsmProperties( self.selectedFastener, reset=True )
         self.finish()
コード例 #7
0
def placeFastenerToLCS(attFstnr, attLink, attPart, attLCS):
    expr = makeExpressionFastener(attLink, attPart, attLCS)
    # indicate the this fastener has been placed with the Assembly4 workbench
    if not hasattr(attFstnr, 'AssemblyType'):
        Asm4.makeAsmProperties(attFstnr)
    attFstnr.AssemblyType = 'Asm4EE'
    # the fastener is attached by its Origin, no extra LCS
    attFstnr.AttachedBy = 'Origin'
    # store the part where we're attached to in the constraints object
    attFstnr.AttachedTo = attLink + '#' + attLCS
    # load the built expression into the Expression field of the constraint
    attFstnr.setExpression('Placement', expr)
    # recompute the object to apply the placement:
    attFstnr.recompute()
    container = attFstnr.getParentGeoFeatureGroup()
    if container:
        container.recompute()
    if attFstnr.Document:
        attFstnr.Document.recompute()
コード例 #8
0
 def Activated(self):
     # check that we have selected a Fastener from the Fastener WB
     selection = getSelectionFS()
     if selection == None:
         return
     # check that the fastener is an Asm4 fastener
     if not hasattr(selection,'AssemblyType'):
         Asm4.makeAsmProperties(selection)
     # we only deal with Asm4 or empty types
     asmType = selection.AssemblyType
     if asmType=='Asm4EE' or asmType=='':
         # now we should be safe, call the UI
         Gui.Control.showDialog( placeFastenerUI() )
     else:
         convert = Asm4.confirmBox("This doesn't seem to be an Assembly4 Fastener")
         if convert:
             Asm4.makeAsmProperties( selection, reset=True )
             selection.AssemblyType = 'Asm4EE'
             Gui.Control.showDialog( placeFastenerUI() )
         return
コード例 #9
0
 def Activated(self):
     # check that the Fasteners WB has been loaded before:
     if not 'FSChangeParams' in Gui.listCommands():
         Gui.activateWorkbench('FastenersWorkbench')
         Gui.activateWorkbench('Assembly4Workbench')
     # check that we have somewhere to put our stuff
     self.asmDoc = App.ActiveDocument
     part = self.getPart()
     if part:
         newFastener = App.ActiveDocument.addObject("Part::FeaturePython",
                                                    self.FStype)
         newFastener.ViewObject.ShapeColor = self.FScolor
         if self.FStype == 'Screw':
             FS.FSScrewObject(newFastener, 'ISO4762', None)
         elif self.FStype == 'Nut':
             FS.FSScrewObject(newFastener, 'ISO4032', None)
         elif self.FStype == 'Washer':
             FS.FSScrewObject(newFastener, 'ISO7089', None)
         elif self.FStype == 'ThreadedRod':
             FS.FSThreadedRodObject(newFastener, None)
         # make the Proxy and stuff
         newFastener.Label = newFastener.Proxy.itemText
         FS.FSViewProviderTree(newFastener.ViewObject)
         # add Asm4 properties if necessary
         Asm4.makeAsmProperties(newFastener, reset=True)
         # add it to the Part
         part.addObject(newFastener)
         # hide "offset" and "invert" properties to avoid confusion as they are not used in Asm4
         if hasattr(newFastener, 'offset'):
             newFastener.setPropertyStatus('offset', 'Hidden')
         if hasattr(newFastener, 'invert'):
             newFastener.setPropertyStatus('invert', 'Hidden')
         newFastener.recompute()
         # ... and select it
         Gui.Selection.clearSelection()
         Gui.Selection.addSelection(newFastener)
         Gui.runCommand('FSChangeParams')
コード例 #10
0
    def __init__(self):
        self.base = QtGui.QWidget()
        self.form = self.base
        iconFile = os.path.join(Asm4.iconPath, 'Place_Link.svg')
        self.form.setWindowIcon(QtGui.QIcon(iconFile))
        self.form.setWindowTitle('Place linked Part')

        # check that we have selected two LCS or an App::Link object
        self.selectedLink = []
        self.selectedLCSA = None
        self.selectedLinkB = None
        self.selectedLCSB = None
        selection = Asm4.getSelectedLink()
        #selectedLCSPair = Asm4.getLinkAndDatum2()
        self.Xtranslation = 0.00
        self.Ytranslation = 0.00
        self.Ztranslation = 0.00
        self.XrotationAngle = 0.00
        self.YrotationAngle = 0.00
        self.ZrotationAngle = 0.00

        # draw the GUI, objects are defined later down
        self.drawUI()
        global taskUI
        taskUI = self

        #Handle single selected App::Link
        if not selection:
            # This shouldn't happen
            FCC.PrintWarning(
                "This is not an error message you are supposed to see, something went wrong\n"
            )
            Gui.Control.closeDialog()
        else:
            self.selectedLink = selection
            Asm4.makeAsmProperties(self.selectedLink)

        #save original AttachmentOffset of linked part
        self.old_LinkAttachmentOffset = self.selectedLink.AttachmentOffset
        self.old_LinkRotation = self.selectedLink.AttachmentOffset.Rotation
        self.old_LinkPosition = self.selectedLink.AttachmentOffset.Base
        # default values correspond to original AttachmentOffset of linked part
        self.Xtranslation = self.old_LinkPosition[0]
        self.Ytranslation = self.old_LinkPosition[1]
        self.Ztranslation = self.old_LinkPosition[2]
        self.XrotationAngle = self.old_LinkRotation.toEuler()[0]
        self.YrotationAngle = self.old_LinkRotation.toEuler()[1]
        self.ZrotationAngle = self.old_LinkRotation.toEuler()[2]

        # save previous view properties
        self.old_OverrideMaterial = self.selectedLink.ViewObject.OverrideMaterial
        self.old_DrawStyle = self.selectedLink.ViewObject.DrawStyle
        self.old_LineWidth = self.selectedLink.ViewObject.LineWidth
        self.old_DiffuseColor = self.selectedLink.ViewObject.ShapeMaterial.DiffuseColor
        self.old_Transparency = self.selectedLink.ViewObject.ShapeMaterial.Transparency
        # set new view properties
        self.selectedLink.ViewObject.OverrideMaterial = True
        self.selectedLink.ViewObject.DrawStyle = DrawStyle
        self.selectedLink.ViewObject.LineWidth = LineWidth
        self.selectedLink.ViewObject.ShapeMaterial.DiffuseColor = DiffuseColor
        self.selectedLink.ViewObject.ShapeMaterial.Transparency = Transparency

        # get the current active document to avoid errors if user changes tab
        self.activeDoc = App.activeDocument()
        # the parent (top-level) assembly is the App::Part called Model (hard-coded)
        self.parentAssembly = self.activeDoc.Model

        # check that the link is an Asm4 link:
        self.isAsm4EE = False
        if hasattr(self.selectedLink, 'AssemblyType'):
            if self.selectedLink.AssemblyType == 'Asm4EE' or self.selectedLink.AssemblyType == '':
                self.isAsm4EE = True
            else:
                Asm4.warningBox(
                    "This Link's assembly type doesn't correspond to this WorkBench"
                )
                return

        # initialize the UI with the current data
        self.attLCStable = []
        self.initUI()
        # now self.parentList and self.parentTable are available

        # find all the linked parts in the assembly
        for objName in self.parentAssembly.getSubObjects():
            # remove the trailing .
            obj = self.activeDoc.getObject(objName[0:-1])
            if obj.TypeId == 'App::Link' and hasattr(obj.LinkedObject,
                                                     'isDerivedFrom'):
                if obj.LinkedObject.isDerivedFrom(
                        'App::Part') or obj.LinkedObject.isDerivedFrom(
                            'PartDesign::Body'):
                    # ... except if it's the selected link itself
                    if obj != self.selectedLink:
                        self.parentTable.append(obj)
                        # add to the drop-down combo box with the assembly tree's parts
                        objIcon = obj.LinkedObject.ViewObject.Icon
                        objText = Asm4.nameLabel(obj)
                        self.parentList.addItem(objIcon, objText, obj)

        # find all the LCS in the selected link
        self.partLCStable = Asm4.getPartLCS(self.selectedLink.LinkedObject)
        # build the list
        self.partLCSlist.clear()
        for lcs in self.partLCStable:
            newItem = QtGui.QListWidgetItem()
            newItem.setText(Asm4.nameLabel(lcs))
            newItem.setIcon(lcs.ViewObject.Icon)
            self.partLCSlist.addItem(newItem)

        # get the old values
        if self.isAsm4EE:
            self.old_AO = self.selectedLink.AttachmentOffset
            self.old_linkLCS = self.selectedLink.AttachedBy[1:]
            (self.old_Parent, separator,
             self.old_parentLCS) = self.selectedLink.AttachedTo.partition('#')
        else:
            self.old_AO = []
            self.old_Parent = ''

        self.old_EE = ''
        # get and store the current expression engine:
        self.old_EE = Asm4.placementEE(self.selectedLink.ExpressionEngine)

        # decode the old ExpressionEngine
        old_Parent = ''
        old_ParentPart = ''
        old_attLCS = ''
        constrName = ''
        linkedDoc = ''
        old_linkLCS = ''
        # if the decode is unsuccessful, old_Expression is set to False and the other things are set to 'None'
        (old_Parent, old_attLCS,
         old_linkLCS) = Asm4.splitExpressionLink(self.old_EE, self.old_Parent)

        # find the old LCS in the list of LCS of the linked part...
        # MatchExactly, MatchContains, MatchEndsWith ...
        lcs_found = self.partLCSlist.findItems(old_linkLCS,
                                               QtCore.Qt.MatchExactly)
        if not lcs_found:
            lcs_found = self.partLCSlist.findItems(old_linkLCS + ' (',
                                                   QtCore.Qt.MatchStartsWith)
        if lcs_found:
            # ... and select it
            self.partLCSlist.setCurrentItem(lcs_found[0])

        # find the oldPart in the part list...
        if old_Parent == 'Parent Assembly':
            parent_found = True
            parent_index = 1
        else:
            parent_found = False
            parent_index = 1
            for item in self.parentTable[1:]:
                if item.Name == old_Parent:
                    parent_found = True
                    break
                else:
                    parent_index = parent_index + 1
        if not parent_found:
            parent_index = 0
        self.parentList.setCurrentIndex(parent_index)
        # this should have triggered self.getPartLCS() to fill the LCS list

        # find the old attachment Datum in the list of the Datums in the linked part...
        lcs_found = self.attLCSlist.findItems(old_attLCS,
                                              QtCore.Qt.MatchExactly)
        if not lcs_found:
            lcs_found = self.attLCSlist.findItems(old_attLCS + ' (',
                                                  QtCore.Qt.MatchStartsWith)
        if lcs_found:
            # ... and select it
            self.attLCSlist.setCurrentItem(lcs_found[0])
コード例 #11
0
    def Activated(self):

        # get the current active document to avoid errors if user changes tab
        self.activeDoc = App.activeDocument()
        # the parent (top-level) assembly is the App::Part called Model (hard-coded)
        self.parentAssembly = self.activeDoc.Model

        # check that we have selected a PartDesign::CoordinateSystem
        self.selectedFastener = []
        selection = self.GetSelection()
        if selection == None:
            self.close()
        else:
            self.selectedFastener = selection

        # check that the fastener is an Asm4 fastener
        if not hasattr(self.selectedFastener,'AssemblyType'):
            Asm4.makeAsmProperties(self.selectedFastener)
        asmType = self.selectedFastener.AssemblyType
        # we only deal with Asm4 or empty types
        if asmType!='Asm4EE' and asmType!='':
            Asm4.warningBox("This doesn't seem to be an Assembly4 Fastener")
            return(False)

        # check where the fastener was attached to
        (self.old_Parent, separator, self.old_parentLCS) = self.selectedFastener.AttachedTo.partition('#')

        # get and store the current expression engine:
        self.old_EE = ''
        old_EE = self.selectedFastener.ExpressionEngine
        if old_EE:
            for ( key, expr ) in old_EE:
                #( key, expr ) = ee
                if key=='Placement':
                    self.old_EE = expr

        # Now we can draw the UI
        self.initUI()
        self.show()

        # decode the old ExpressionEngine
        # if the decode is unsuccessful, old_Expression is set to False
        # and old_attPart and old_attLCS are set to 'None'
        old_Parent = ''
        old_parentPart = ''
        old_parentLCS = ''
        if  self.old_EE and self.old_Parent:
            ( old_Parent, old_parentPart, old_parentLCS ) = self.splitExpressionFastener( self.old_EE, self.old_Parent )
        #self.expression.setText( 'old_Parent = '+ old_Parent )

        # We get all the App::Link parts in the assembly 
        self.asmParts = []
        # the first item is "Select linked Part" therefore we add an empty object
        self.asmParts.append( [] )
        # We also add the parent assembly
        self.asmParts.append( self.parentAssembly )
        # Add it as first element to the drop-down combo-box
        parentIcon = self.parentAssembly.ViewObject.Icon
        self.parentList.addItem( parentIcon, 'Parent Assembly', self.parentAssembly )
        # find all the linked parts in the assembly
        for obj in self.activeDoc.findObjects("App::Link"):
            if obj.LinkedObject.isDerivedFrom('App::Part'):
                # add it to our tree table if it's a link to an App::Part ...
                self.asmParts.append( obj )
                # ... and add to the drop-down combo box with the assembly tree's parts
                objIcon = obj.LinkedObject.ViewObject.Icon
                self.parentList.addItem( objIcon, obj.Name, obj)

        # find the oldPart in the part list...
        parent_index = 1
        if old_Parent == 'Parent Assembly':
            parent_found = True
        else:
            parent_found = False
            for item in self.asmParts[1:]:
                if item.Name == old_Parent:
                    parent_found = True
                    break
                else:
                    parent_index = parent_index +1
        if not parent_found:
            parent_index = 0
        self.parentList.setCurrentIndex( parent_index )
        # this should have triggered self.getPartLCS() to fill the LCS list


        # find the oldLCS in the list of LCS of the linked part...
        lcs_found = []
        lcs_found = self.attLCSlist.findItems( old_parentLCS, QtCore.Qt.MatchExactly )
        if lcs_found:
            # ... and select it
            self.attLCSlist.setCurrentItem( lcs_found[0] )
        else:
            # may-be it was renamed, see if we can find it as (name)
            lcs_found = self.attLCSlist.findItems( '('+old_parentLCS+')', QtCore.Qt.MatchContains )
            if lcs_found:
                self.attLCSlist.setCurrentItem( lcs_found[0] )