diff --git a/GuiA2p/Resources/ui/a2p_prefs.ui b/GuiA2p/Resources/ui/a2p_prefs.ui index 72cdce14..26d0ef9a 100644 --- a/GuiA2p/Resources/ui/a2p_prefs.ui +++ b/GuiA2p/Resources/ui/a2p_prefs.ui @@ -196,10 +196,26 @@ 30 40 521 - 71 + 95 + + + + Show constraints on toolbar + + + true + + + showConstraintsOnToolbar + + + Mod/A2plus + + + diff --git a/InitGui.py b/InitGui.py index 0e073af6..22b8dca0 100644 --- a/InitGui.py +++ b/InitGui.py @@ -55,7 +55,8 @@ def Initialize(self): import a2p_MuxAssembly import a2p_partinformation import a2p_constraintDialog - import a2p_bom #bill of materials == partslist + import a2p_constraintcommands + import a2p_bom # bom == bill of materials == partslist partCommands = [ 'a2p_ImportPart', @@ -65,11 +66,32 @@ def Initialize(self): 'a2p_ConvertPart', 'a2p_editImportedPart', ] - constraintCommands = [ - 'a2p_ConstraintDialogCommand', - 'a2p_EditConstraintCommand', - 'a2p_DeleteConnectionsCommand', - ] + + if a2plib.SHOW_CONSTRAINTS_ON_TOOLBAR: + constraintCommands = [ + 'a2p_ConstraintDialogCommand', + 'a2p_EditConstraintCommand', + 'a2p_PointIdentityConstraintCommand', + 'a2p_PointOnLineConstraintCommand', + 'a2p_PointOnPlaneConstraintCommand', + 'a2p_SphericalSurfaceConstraintCommand', + 'a2p_CircularEdgeConnection', + 'a2p_AxialConstraintCommand', + 'a2p_AxisParallelConstraintCommand', + 'a2p_AxisPlaneParallelCommand', + 'a2p_PlanesParallelConstraintCommand', + 'a2p_PlaneCoincidentConstraintCommand', + 'a2p_AngledPlanesConstraintCommand', + + 'a2p_DeleteConnectionsCommand', + ] + else: + constraintCommands = [ + 'a2p_ConstraintDialogCommand', + 'a2p_EditConstraintCommand', + 'a2p_DeleteConnectionsCommand', + ] + solverCommands = [ 'a2p_SolverCommand', #'a2p_newSolverCommand', diff --git a/a2p_constraintDialog.py b/a2p_constraintDialog.py index c1baa14e..49c74cff 100644 --- a/a2p_constraintDialog.py +++ b/a2p_constraintDialog.py @@ -654,14 +654,14 @@ def manageConstraint(self): @QtCore.Slot() def onAcceptConstraint(self): - self.constraintValueBox.deleteLater() + #self.constraintValueBox.deleteLater() a2plib.setConstraintEditorRef(None) self.activeConstraint = None FreeCADGui.Selection.clearSelection() @QtCore.Slot() def onDeleteConstraint(self): - self.constraintValueBox.deleteLater() + #self.constraintValueBox.deleteLater() a2plib.setConstraintEditorRef(None) self.activeConstraint = None FreeCADGui.Selection.clearSelection() @@ -722,11 +722,19 @@ def onSpericalConstraintButton(self): self.manageConstraint() #============================================================================== -def getMoveDistToScreenCenter(widg): - w = QtGui.QApplication.desktop().width() - h = QtGui.QApplication.desktop().height() - center = QtCore.QPoint(w/2,h/2) - return center- widg.rect().center() +def getMoveDistToFcCenter(widg): + mw = FreeCADGui.getMainWindow() + fcFrame = QtGui.QDesktopWidget.geometry(mw) + x = fcFrame.x() + y = fcFrame.y() + width = fcFrame.width() + height = fcFrame.height() + + centerX = x + width/2 + centerY = y + height/2 + fcCenter = QtCore.QPoint(centerX,centerY) + + return fcCenter- widg.rect().center() #============================================================================== class a2p_ConstraintValuePanel(QtGui.QDockWidget): @@ -738,6 +746,7 @@ def __init__(self,constraintObject, mode): self.constraintObject = constraintObject self.resize(300,300) # + print (constraintObject) cvw = a2p_ConstraintValueWidget( None, constraintObject, @@ -754,15 +763,19 @@ def __init__(self,constraintObject, mode): self.setFloating(True) self.activateWindow() self.setAllowedAreas(QtCore.Qt.NoDockWidgetArea) - self.move(getMoveDistToScreenCenter(self)) + self.move(getMoveDistToFcCenter(self)) a2plib.setConstraintEditorRef(self) def onAcceptConstraint(self): self.Accepted.emit() + a2plib.setConstraintEditorRef(None) + self.deleteLater() def onDeleteConstraint(self): self.Deleted.emit() + a2plib.setConstraintEditorRef(None) + self.deleteLater() def closeEvent(self,event): self.widget().cancelOperation() @@ -783,7 +796,7 @@ def __init__(self): self.setFloating(True) self.activateWindow() self.setAllowedAreas(QtCore.Qt.NoDockWidgetArea) - self.move(getMoveDistToScreenCenter(self)) + self.move(getMoveDistToFcCenter(self)) a2plib.setConstraintDialogRef(self) # diff --git a/a2p_constraintcommands.py b/a2p_constraintcommands.py new file mode 100644 index 00000000..73072cde --- /dev/null +++ b/a2p_constraintcommands.py @@ -0,0 +1,314 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2019 kbwbe * +#* * +#* Portions of code based on hamish's assembly 2 * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* This program is distributed in the hope that it will be useful, * +#* but WITHOUT ANY WARRANTY; without even the implied warranty of * +#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +#* GNU Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +import FreeCAD, FreeCADGui, Part +from PySide import QtGui, QtCore +import os, sys, math, copy +from a2p_viewProviderProxies import * +from FreeCAD import Base + +from a2plib import * +from a2p_solversystem import solveConstraints +import a2p_constraints, a2p_constraintDialog + +#============================================================================== +class a2p_PointIdentityConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.PointIdentityConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.PointIdentityConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_PointIdentity.svg', + 'MenuText': 'Add PointIdentity Constraint', + 'ToolTip': a2p_constraints.PointIdentityConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_PointIdentityConstraintCommand', a2p_PointIdentityConstraintCommand()) + +#============================================================================== +class a2p_PointOnLineConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.PointOnLineConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.PointOnLineConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_PointOnLineConstraint.svg', + 'MenuText': 'Add PointOnLine constraint', + 'ToolTip': a2p_constraints.PointOnLineConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_PointOnLineConstraintCommand', a2p_PointOnLineConstraintCommand()) + +#============================================================================== +class a2p_PointOnPlaneConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.PointOnPlaneConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.PointOnPlaneConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_PointOnPlaneConstraint.svg', + 'MenuText': 'Add PointOnPlane constraint', + 'ToolTip': a2p_constraints.PointOnPlaneConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_PointOnPlaneConstraintCommand', a2p_PointOnPlaneConstraintCommand()) +#============================================================================== +class a2p_SphericalSurfaceConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.SphericalConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.SphericalConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_SphericalSurfaceConstraint.svg', + 'MenuText': 'Add a spherical constraint', + 'ToolTip': a2p_constraints.SphericalConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_SphericalSurfaceConstraintCommand', a2p_SphericalSurfaceConstraintCommand()) +#============================================================================== +class a2p_CircularEdgeConnectionCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.CircularEdgeConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.CircularEdgeConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_CircularEdgeConstraint.svg' , + 'MenuText': 'Add circular edge connection', + 'ToolTip': a2p_constraints.CircularEdgeConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_CircularEdgeConnection', a2p_CircularEdgeConnectionCommand()) +#============================================================================== +class a2p_AxialConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.AxialConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.AxialConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_AxialConstraint.svg', + 'MenuText': 'Add axial constraint', + 'ToolTip': a2p_constraints.AxialConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_AxialConstraintCommand', a2p_AxialConstraintCommand()) +#============================================================================== +class a2p_AxisParallelConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.AxisParallelConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.AxisParallelConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : ':/icons/a2p_AxisParallelConstraint.svg', + 'MenuText': 'Add axisParallel constraint', + 'ToolTip': a2p_constraints.AxisParallelConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_AxisParallelConstraintCommand', a2p_AxisParallelConstraintCommand()) +#============================================================================== +class a2p_AxisPlaneParallelCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.AxisPlaneParallelConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.AxisPlaneParallelConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : ':/icons/a2p_AxisPlaneParallelConstraint.svg', + 'MenuText': 'axisPlaneParallel constraint', + 'ToolTip': a2p_constraints.AxisPlaneParallelConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_AxisPlaneParallelCommand', a2p_AxisPlaneParallelCommand()) +#============================================================================== +class a2p_PlanesParallelConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.PlanesParallelConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.PlanesParallelConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_PlanesParallelConstraint.svg', + 'MenuText': 'Add planesParallel constraint', + 'ToolTip': a2p_constraints.PlanesParallelConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_PlanesParallelConstraintCommand', a2p_PlanesParallelConstraintCommand()) +#============================================================================== +class a2p_PlaneCoincidentConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.PlaneConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + def IsActive(self): + return a2p_constraints.PlaneConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_PlaneCoincidentConstraint.svg', + 'MenuText': 'Add plane constraint', + 'ToolTip': a2p_constraints.PlaneConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_PlaneCoincidentConstraintCommand', a2p_PlaneCoincidentConstraintCommand()) +#============================================================================== +class a2p_AngledPlanesConstraintCommand: + def Activated(self): + selection = FreeCADGui.Selection.getSelectionEx() + + c = a2p_constraints.AngledPlanesConstraint(selection) + cvp = a2p_constraintDialog.a2p_ConstraintValuePanel( + c.constraintObject, + 'createConstraint' + ) + FreeCADGui.Selection.clearSelection() + + + def IsActive(self): + return a2p_constraints.AngledPlanesConstraint.isValidSelection( + FreeCADGui.Selection.getSelectionEx() + ) + + def GetResources(self): + return { + 'Pixmap' : path_a2p + '/icons/a2p_AngleConstraint.svg', + 'MenuText': 'angle between planes constraint', + 'ToolTip': a2p_constraints.AngledPlanesConstraint.getToolTip() + } + +FreeCADGui.addCommand('a2p_AngledPlanesConstraintCommand', a2p_AngledPlanesConstraintCommand()) + +#============================================================================== \ No newline at end of file diff --git a/a2p_constraints.py b/a2p_constraints.py index 4085c5ce..c475de76 100644 --- a/a2p_constraints.py +++ b/a2p_constraints.py @@ -132,6 +132,11 @@ def calcInitialValues(self): @staticmethod def getToolTip(self): return 'Invalid Base Class BasicConstraint' + + @staticmethod + def isValidSelection(selection): + return True + #============================================================================== class PointIdentityConstraint(BasicConstraint): @@ -153,7 +158,21 @@ def getToolTip(): selection: 1.) select a vertex on a part 2.) select a vertex on another part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if vertexSelected(s1) and vertexSelected(s2): + validSelection = True + return validSelection + #============================================================================== class PointOnLineConstraint(BasicConstraint): def __init__(self,selection): @@ -173,7 +192,21 @@ def getToolTip(): Add a pointOnLine constraint between two objects 1.) select a vertex from a part 2.) select a line (linear edge) on another part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if vertexSelected(s1) and LinearEdgeSelected(s2): + validSelection = True + return validSelection + #============================================================================== class PointOnPlaneConstraint(BasicConstraint): def __init__(self,selection): @@ -204,7 +237,24 @@ def getToolTip(): Add a pointOnPlane constraint between two objects 1.) select a vertex or a center of a circle 2.) select a plane on other part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if ( + (vertexSelected(s1) or CircularEdgeSelected(s1)) and + planeSelected(s2) + ): + validSelection = True + return validSelection + #============================================================================== class CircularEdgeConstraint(BasicConstraint): def __init__(self,selection): @@ -236,7 +286,21 @@ def getToolTip(): selection-hint: 1.) select circular edge on first importPart 2.) select circular edge on other importPart + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if CircularEdgeSelected(s1) and CircularEdgeSelected(s2): + validSelection = True + return validSelection + #============================================================================== class AxialConstraint(BasicConstraint): def __init__(self,selection): @@ -269,7 +333,26 @@ def getToolTip(): Selection: 1.) Select cylindrical face or linear edge on a part 2.) Select cylindrical face or linear edge on another part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + + def ValidSelection(selectionExObj): + return cylindricalPlaneSelected(selectionExObj) \ + or LinearEdgeSelected(selectionExObj) + + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if ValidSelection(s1) and ValidSelection(s2): + validSelection = True + return validSelection + #============================================================================== class AxisParallelConstraint(BasicConstraint): def __init__(self,selection): @@ -301,7 +384,24 @@ def getToolTip(): select: 1.) linearEdge or cylinderFace from a part 2.) linearEdge or cylinderFace from another part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if ( + (LinearEdgeSelected(s1) or cylindricalPlaneSelected(s1)) and + (LinearEdgeSelected(s2) or cylindricalPlaneSelected(s2)) + ): + validSelection = True + return validSelection + #============================================================================== class AxisPlaneParallelConstraint(BasicConstraint): def __init__(self,selection): @@ -326,7 +426,24 @@ def getToolTip(): This constraint adjusts an axis parallel to a selected plane. The parts are not moved to be coincident. + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if ( + (LinearEdgeSelected(s1) or cylindricalPlaneSelected(s1)) and + planeSelected(s2) + ): + validSelection = True + return validSelection + #============================================================================== class PlanesParallelConstraint(BasicConstraint): def __init__(self,selection): @@ -360,7 +477,23 @@ def getToolTip(): select: 1.) select a plane on a part 2.) select a plane from another part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + #if not planeSelected(s1): #???? + # s2, s1 = s1, s2 #????? + if planeSelected(s1) and planeSelected(s2): + validSelection = True + return validSelection + #============================================================================== class PlaneConstraint(BasicConstraint): def __init__(self,selection): @@ -393,7 +526,23 @@ def getToolTip(): select: 1.) select a plane on a part 2.) select a plane from another part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + #if not planeSelected(s1): + # s2, s1 = s1, s2 + if planeSelected(s1) and planeSelected(s2): + validSelection = True + return validSelection + #============================================================================== class AngledPlanesConstraint(BasicConstraint): def __init__(self,selection): @@ -431,7 +580,21 @@ def getToolTip(): You could get strange results. Better for that is using planesParallelConstraint. + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if ( planeSelected(s1) and planeSelected(s2)): + validSelection = True + return validSelection + #============================================================================== class SphericalConstraint(BasicConstraint): def __init__(self,selection): @@ -453,7 +616,22 @@ def getToolTip(): Selection options: - spherical surface or vertex on a part - spherical surface or vertex on another part + +Button gets active after +correct selection. ''' + + @staticmethod + def isValidSelection(selection): + validSelection = False + if len(selection) == 2: + s1, s2 = selection + if s1.ObjectName != s2.ObjectName: + if ( vertexSelected(s1) or sphericalSurfaceSelected(s1)) \ + and ( vertexSelected(s2) or sphericalSurfaceSelected(s2)): + validSelection = True + return validSelection + #============================================================================== diff --git a/a2plib.py b/a2plib.py index 89859b65..160f220f 100644 --- a/a2plib.py +++ b/a2plib.py @@ -37,6 +37,7 @@ AUTOSOLVE_ENABLED = preferences.GetBool('autoSolve', True) RELATIVE_PATHES_ENABLED = preferences.GetBool('useRelativePathes',True) FORCE_FIXED_POSITION = preferences.GetBool('forceFixedPosition',True) +SHOW_CONSTRAINTS_ON_TOOLBAR= preferences.GetBool('showConstraintsOnToolbar',True) SAVED_TRANSPARENCY = []