constraint: reorganise constraints

Extended some constraint to support BaseMulti.
This commit is contained in:
Zheng, Lei 2018-07-26 10:56:25 +08:00
parent 731bdb071c
commit 819dee3381
3 changed files with 255 additions and 136 deletions

View File

@ -383,6 +383,10 @@ class ConstraintCommand:
def _toolbarName(self): def _toolbarName(self):
return self.tp._toolbarName return self.tp._toolbarName
@property
def _toolbarVisible(self):
return self.tp._toolbarVisible
def workbenchActivated(self): def workbenchActivated(self):
self._active = None self._active = None
@ -399,25 +403,15 @@ class ConstraintCommand:
return self.tp.GetResources() return self.tp.GetResources()
def Activated(self): def Activated(self):
from .assembly import AsmConstraint self.tp.activate()
guilogger.report('constraint "{}" command exception'.format(
self.tp.getName()), AsmConstraint.make,self.tp._id)
def IsActive(self): def IsActive(self):
if not FreeCAD.ActiveDocument: if not FreeCAD.ActiveDocument:
return False return False
if self._active is None: if self._active is None:
self.checkActive() self._active = self.tp.checkActive()
return self._active return self._active
def checkActive(self):
from .assembly import AsmConstraint
if guilogger.catchTrace('selection "{}" exception'.format(
self.tp.getName()), AsmConstraint.getSelection, self.tp._id):
self._active = True
else:
self._active = False
def onSelectionChange(self,hasSelection): def onSelectionChange(self,hasSelection):
self._active = None if hasSelection else False self._active = None if hasSelection else False
@ -482,12 +476,12 @@ class Constraint(ProxyType):
return mcs.getProxy(obj).prepare(obj,solver) return mcs.getProxy(obj).prepare(obj,solver)
@classmethod @classmethod
def getFixedParts(mcs,solver,cstrs,parts): def getFixedParts(mcs,solver,cstrs,partGroup):
firstInfo = None firstInfo = None
ret = set() ret = partGroup.Proxy.derivedParts
from .assembly import isTypeOf, AsmWorkPlane from .assembly import isTypeOf, AsmWorkPlane
for obj in parts: for obj in partGroup.Group:
if not hasattr(obj,'Placement'): if not hasattr(obj,'Placement'):
ret.add(obj) ret.add(obj)
elif isTypeOf(obj,AsmWorkPlane) and getattr(obj,'Fixed',False): elif isTypeOf(obj,AsmWorkPlane) and getattr(obj,'Fixed',False):
@ -603,6 +597,7 @@ class Base(with_metaclass(Constraint, object)):
_workplane = False _workplane = False
_props = [] _props = []
_toolbarName = 'Assembly3 Constraints' _toolbarName = 'Assembly3 Constraints'
_toolbarVisible = True
_iconName = 'Assembly_ConstraintGeneral.svg' _iconName = 'Assembly_ConstraintGeneral.svg'
_menuText = 'Create "{}" constraint' _menuText = 'Create "{}" constraint'
@ -613,14 +608,31 @@ class Base(with_metaclass(Constraint, object)):
def init(cls,_obj): def init(cls,_obj):
pass pass
@classmethod
def activate(cls):
from .assembly import AsmConstraint
guilogger.report('constraint "{}" command exception'.format(
cls.getName()), AsmConstraint.make, cls._id)
@classmethod
def checkActive(cls):
from .assembly import AsmConstraint
if guilogger.catchTrace('selection "{}" exception'.format(
cls.getName()), AsmConstraint.getSelection, cls._id):
return True
else:
return False
@classmethod @classmethod
def getPropertyInfoList(cls): def getPropertyInfoList(cls):
return cls._props return cls._props
@classmethod @classmethod
def constraintFunc(cls,obj,solver): def constraintFunc(cls,obj,solver,name=None):
try: try:
return getattr(solver.system,'add'+cls.getName()) if not name:
name = getattr(cls,'_cstrFuncName','add'+cls.getName())
return getattr(solver.system,name)
except AttributeError: except AttributeError:
logger.warn('{} not supported in solver "{}"'.format( logger.warn('{} not supported in solver "{}"'.format(
cstrName(obj),solver.getName())) cstrName(obj),solver.getName()))
@ -689,13 +701,12 @@ class Base(with_metaclass(Constraint, object)):
@classmethod @classmethod
def prepare(cls,obj,solver): def prepare(cls,obj,solver):
func = cls.constraintFunc(obj,solver) func = cls.constraintFunc(obj,solver)
if func: if not func:
return
params = cls.getPropertyValues(obj) + cls.getEntities(obj,solver) params = cls.getPropertyValues(obj) + cls.getEntities(obj,solver)
ret = func(*params,group=solver.group) ret = func(*params,group=solver.group)
solver.system.log('{}: {}'.format(cstrName(obj),ret)) solver.system.log('{}: {}'.format(cstrName(obj),ret))
return ret return ret
else:
logger.warn('{} no constraint func'.format(cstrName(obj)))
@classmethod @classmethod
def hasFixedPart(cls,_obj): def hasFixedPart(cls,_obj):
@ -850,23 +861,37 @@ class BaseMulti(Base):
_id = -1 _id = -1
_entityDef = (_wa,) _entityDef = (_wa,)
@classmethod
def onRegister(cls):
assert(not cls._workplane)
assert(len(cls._entityDef)<=2)
@classmethod @classmethod
def check(cls,elements,checkCount=False): def check(cls,elements,checkCount=False):
if checkCount and len(elements)<2: if checkCount and len(elements)<2:
raise RuntimeError('Constraint "{}" requires at least two ' raise RuntimeError('Constraint "{}" requires at least two '
'elements'.format(cls.getName())) 'elements'.format(cls.getName()))
for info in elements: count = min(len(elements),len(cls._entityDef))
for i,entityDef in enumerate(cls._entityDef[:count]):
info = elements[i]
msg = entityDef(None,info.Part,info.Subname,info.Shape)
if msg:
raise RuntimeError('Constraint "{}" requires the {} element '
'to be of {}'.format(cls.getName(),_ordinal[i],msg))
if len(elements)<=count:
return
i = len(cls._entityDef)
for info in elements[i:]:
msg = cls._entityDef[0](None,info.Part,info.Subname,info.Shape) msg = cls._entityDef[0](None,info.Part,info.Subname,info.Shape)
if msg: if msg:
raise RuntimeError('Constraint "{}" requires all the element ' raise RuntimeError('Constraint "{}" requires the {} element '
'to be of {}'.format(cls.getName(),msg)) 'onwards to all be of {}'.format(
return cls.getName(),_ordinal[i],msg))
@classmethod @classmethod
def prepare(cls,obj,solver): def prepare(cls,obj,solver):
func = cls.constraintFunc(obj,solver); func = cls.constraintFunc(obj,solver);
if not func: if not func:
logger.warn('{} no constraint func'.format(cstrName(obj)))
return return
props = cls.getPropertyValues(obj) props = cls.getPropertyValues(obj)
ret = [] ret = []
@ -928,17 +953,25 @@ class BaseMulti(Base):
logger.warn('{} has no effective constraint'.format(cstrName(obj))) logger.warn('{} has no effective constraint'.format(cstrName(obj)))
return return
e0 = None e0 = None
firstInfo = None e = None
for e in elements: info0 = None
info = e.Proxy.getInfo() idx0 = 1 if len(cls._entityDef)>1 else 0
for i,element in enumerate(elements):
info = element.Proxy.getInfo()
partInfo = solver.getPartInfo(info) partInfo = solver.getPartInfo(info)
if not e0: if i==idx0:
e0 = cls._entityDef[0](solver,partInfo,info.Subname,info.Shape) e0 = cls._entityDef[idx0](
firstInfo = partInfo solver,partInfo,info.Subname,info.Shape)
info0 = partInfo
else: else:
e = cls._entityDef[0](solver,partInfo,info.Subname,info.Shape) e = cls._entityDef[0](solver,partInfo,info.Subname,info.Shape)
if e0 and e:
if idx0:
params = props + [e,e0]
solver.system.checkRedundancy(obj,partInfo,info0)
else:
params = props + [e0,e] params = props + [e0,e]
solver.system.checkRedundancy(obj,firstInfo,partInfo) solver.system.checkRedundancy(obj,info0,partInfo)
h = func(*params,group=solver.group) h = func(*params,group=solver.group)
if isinstance(h,(list,tuple)): if isinstance(h,(list,tuple)):
ret += list(h) ret += list(h)
@ -953,7 +986,6 @@ class BaseCascade(BaseMulti):
return super(BaseCascade,cls).prepare(obj,solver) return super(BaseCascade,cls).prepare(obj,solver)
func = cls.constraintFunc(obj,solver); func = cls.constraintFunc(obj,solver);
if not func: if not func:
logger.warn('{} no constraint func'.format(cstrName(obj)))
return return
props = cls.getPropertyValues(obj) props = cls.getPropertyValues(obj)
prev = None prev = None
@ -984,20 +1016,22 @@ class BaseCascade(BaseMulti):
return ret return ret
class PlaneAlignment(BaseCascade):
_id = 37
_iconName = 'Assembly_ConstraintAlignment.svg'
_props = ['Cascade','Offset'] + _AngleProps
_tooltip = \
'Add a "{}" constraint to align planar faces of two or more parts.\n'\
'The faces become coplanar or parallel with an optional distance'
class PlaneCoincident(BaseCascade): class PlaneCoincident(BaseCascade):
_id = 35 _id = 35
_iconName = 'Assembly_ConstraintCoincidence.svg' _iconName = 'Assembly_ConstraintCoincidence.svg'
_props = ['Multiply','Cascade','Offset','OffsetX','OffsetY'] + _AngleProps _props = ['Multiply','Cascade','Offset','OffsetX','OffsetY'] + _AngleProps
_tooltip = \ _tooltip = \
'Add a "{}" constraint to conincide planes of two or more parts.\n'\ 'Add a "{}" constraint to conincide planar faces of two or more parts.\n'\
'The planes are coincided at their centers with an optional distance.' 'The faces are coincided at their centers with an optional distance.'
class PlaneAlignment(BaseCascade):
_id = 37
_iconName = 'Assembly_ConstraintAlignment.svg'
_props = ['Cascade','Offset'] + _AngleProps
_tooltip = 'Add a "{}" constraint to rotate planes of two or more parts\n'\
'into the same orientation'
class AxialAlignment(BaseMulti): class AxialAlignment(BaseMulti):
@ -1005,15 +1039,18 @@ class AxialAlignment(BaseMulti):
_entityDef = (_lna,) _entityDef = (_lna,)
_iconName = 'Assembly_ConstraintAxial.svg' _iconName = 'Assembly_ConstraintAxial.svg'
_props = ['Multiply'] + _AngleProps _props = ['Multiply'] + _AngleProps
_tooltip = 'Add a "{}" constraint to align planes of two or more parts.\n'\ _tooltip = 'Add a "{}" constraint to align edges/faces of two or\n'\
'The planes are aligned at the direction of their surface normal axis.' 'more parts. The constraint acceps linear edges, which become\n'\
'colinear, and planar faces, which are aligned uses their surface\n'\
'normal axis, and cylindrical face, which are aligned using the\n'\
'axial direction. Different types of geometry elements can be mixed.'
class SameOrientation(BaseMulti): class SameOrientation(BaseMulti):
_id = 2 _id = 2
_entityDef = (_n,) _entityDef = (_n,)
_iconName = 'Assembly_ConstraintOrientation.svg' _iconName = 'Assembly_ConstraintOrientation.svg'
_tooltip = 'Add a "{}" constraint to align planes of two or more parts.\n'\ _tooltip = 'Add a "{}" constraint to align faces of two or more parts.\n'\
'The planes are aligned to have the same orientation (i.e. rotation)' 'The planes are aligned to have the same orientation (i.e. rotation)'
@ -1022,22 +1059,18 @@ class MultiParallel(BaseMulti):
_entityDef = (_lw,) _entityDef = (_lw,)
_iconName = 'Assembly_ConstraintMultiParallel.svg' _iconName = 'Assembly_ConstraintMultiParallel.svg'
_props = _AngleProps _props = _AngleProps
_tooltip = 'Add a "{}" constraint to make planes ormal or linear edges\n'\ _tooltip = 'Add a "{}" constraint to make planar faces or linear edges\n'\
'of two or more parts parallel.' 'of two or more parts parallel.'
class Base2(Base): class Angle(Base):
_id = -1
_toolbarName = 'Assembly3 Constraints2'
class Angle(Base2):
_id = 27 _id = 27
_entityDef = (_ln,_ln) _entityDef = (_ln,_ln)
_workplane = True _workplane = True
_props = ["Angle","Supplement"] _props = ["Angle","Supplement"]
_iconName = 'Assembly_ConstraintAngle.svg' _iconName = 'Assembly_ConstraintAngle.svg'
_tooltip = 'Add a "{}" constraint to set the angle of planes or linear\n'\ _tooltip = \
'Add a "{}" constraint to set the angle of planar faces or linear\n'\
'edges of two parts.' 'edges of two parts.'
@classmethod @classmethod
@ -1046,19 +1079,19 @@ class Angle(Base2):
obj.Angle = utils.getElementsAngle(shapes[0],shapes[1]) obj.Angle = utils.getElementsAngle(shapes[0],shapes[1])
class Perpendicular(Base2): class Perpendicular(Base):
_id = 28 _id = 28
_entityDef = (_lw,_lw) _entityDef = (_lw,_lw)
_workplane = True _workplane = True
_iconName = 'Assembly_ConstraintPerpendicular.svg' _iconName = 'Assembly_ConstraintPerpendicular.svg'
_tooltip = 'Add a "{}" constraint to make planes or linear edges of two\n'\ _tooltip = \
'Add a "{}" constraint to make planar faces or linear edges of two\n'\
'parts perpendicular.' 'parts perpendicular.'
@classmethod @classmethod
def prepare(cls,obj,solver): def prepare(cls,obj,solver):
system = solver.system system = solver.system
params = cls.getEntities(obj,solver) e1,e2 = cls.getEntities(obj,solver)[:2]
e1,e2 = params[0],params[1]
isPlane = isinstance(e1,list),isinstance(e2,list) isPlane = isinstance(e1,list),isinstance(e2,list)
if all(isPlane): if all(isPlane):
ret = system.addPerpendicular(e1[2],e2[2],group=solver.group) ret = system.addPerpendicular(e1[2],e2[2],group=solver.group)
@ -1071,45 +1104,58 @@ class Perpendicular(Base2):
return ret return ret
class Parallel(Base2): class PointsCoincident(Base):
_id = -1
_entityDef = (_ln,_ln)
_workplane = True
_iconName = 'Assembly_ConstraintParallel.svg'
_tooltip = 'Add a "{}" constraint to make planes or linear edges of two\n'\
'parts parallel.'
class PointsCoincident(Base2):
_id = 1 _id = 1
_entityDef = (_p,_p) _entityDef = (_p,_p)
_workplane = True _workplane = True
_iconName = 'Assembly_ConstraintPointsCoincident.svg' _iconName = 'Assembly_ConstraintPointCoincident.svg'
_tooltip = 'Add a "{}" constraint to conincide two points.' _tooltips = 'Add a "{}" constraint to conincide two points in 2D or 3D'
class PointInPlane(Base2): class PointInPlane(BaseMulti):
_id = 3 _id = 3
_entityDef = (_p,_w) _entityDef = (_p,_w)
_iconName = 'Assembly_ConstraintPointInPlane.svg' _iconName = 'Assembly_ConstraintPointInPlane.svg'
_tooltip = 'Add a "{}" to constrain a point inside a plane.' _tooltip = 'Add a "{}" to constrain one or more point inside a plane.'
class PointOnLine(Base2): class PointOnLine(Base):
_id = 4 _id = 4
_entityDef = (_p,_l) _entityDef = (_p,_lna)
_workplane = True _workplane = True
_iconName = 'Assembly_ConstraintPointOnLine.svg' _iconName = 'Assembly_ConstraintPointOnLine.svg'
_tooltip = 'Add a "{}" to constrain a point on to a line.' _tooltip = 'Add a "{}" to constrain a point on to a line in 2D or 3D.'
@classmethod
def prepare(cls,obj,solver):
func = cls.constraintFunc(obj,solver)
if not func:
return
params = cls.getEntities(obj,solver)
if isinstance(params[1], NormalInfo):
params[1] = params[1].ln
else:
params[1] = params[1].entity
ret = func(*params,group=solver.group)
solver.system.log('{}: {}'.format(cstrName(obj),ret))
return ret
class PointsDistance(Base2): class PointsOnCircle(BaseMulti):
_id = 5 _id = 26
_entityDef = (_p,_p) _entityDef = (_p,_c)
_workplane = True _iconName = 'Assembly_ConstraintPointOnCircle.svg'
_props = ["Distance"] _tooltip='Add a "{}" to constrain one or more points on to a clyndrical\n'\
'plane defined by a cricle.'
_cstrFuncName = 'addPointOnCircle'
class PointsDistance(BaseCascade):
_id = 44
_entityDef = (_p,)
_props = ["Cascade","Distance"]
_iconName = 'Assembly_ConstraintPointsDistance.svg' _iconName = 'Assembly_ConstraintPointsDistance.svg'
_tooltip = 'Add a "{}" to constrain the distance of two points.' _tooltip = 'Add a "{}" to constrain the distance of two or more points.'
@classmethod @classmethod
def init(cls,obj): def init(cls,obj):
@ -1118,40 +1164,60 @@ class PointsDistance(Base2):
obj.Distance = points[0].distanceToPoint(points[1]) obj.Distance = points[0].distanceToPoint(points[1])
class PointsProjectDistance(Base2): class PointsPlaneDistance(BaseMulti):
_id = 6
_entityDef = (_p,_p,_l)
_props = ["Distance"]
_iconName = 'Assembly_ConstraintPointsProjectDistance.svg'
_tooltip = 'Add a "{}" to constrain the distance of two points\n' \
'projected on a line.'
class PointPlaneDistance(Base2):
_id = 7 _id = 7
_entityDef = (_p,_w) _entityDef = (_p,_w)
_props = ["Distance"] _props = ["Distance"]
_iconName = 'Assembly_ConstraintPointPlaneDistance.svg' _iconName = 'Assembly_ConstraintPointPlaneDistance.svg'
_tooltip='Add a "{}" to constrain the distance between a point and a plane' _tooltip='Add a "{}" to constrain the distance between one or more points '\
'and a plane'
_cstrFuncName = 'addPointPlaneDistance'
class PointLineDistance(Base2): class PointLineDistance(Base):
_id = 8 _id = 8
_entityDef = (_p,_l) _entityDef = (_p,_l)
_workplane = True _workplane = True
_props = ["Distance"] _props = ["Distance"]
_iconName = 'Assembly_ConstraintPointLineDistance.svg' _iconName = 'Assembly_ConstraintPointLineDistance.svg'
_tooltip='Add a "{}" to constrain the distance between a point and a line' _tooltip='Add a "{}" to constrain the distance between a point '\
'and a linear edge in 2D or 3D'
class EqualPointLineDistance(Base2): class More(Base):
_id = 13 _id = 47
_entityDef = (_p,_l,_p,_l) _iconName = 'Assembly_ConstraintMore.svg'
_tooltip='Toggle toolbars for more constraints'
@classmethod
def activate(cls):
gui.AsmCmdManager.toggleToolbars()
@classmethod
def checkActive(cls):
return True
class Base2(Base):
_id = -1
_toolbarName = 'Assembly3 Constraints2'
_toolbarVisible = False
class PointDistance(Base2):
_id = 5
_entityDef = (_p,_p)
_workplane = True _workplane = True
_iconName = 'Assembly_ConstraintEqualPointLineDistance.svg' _props = ["Distance"]
_tooltip='Add a "{}" to constrain the distance between a point and a\n'\ _iconName = 'Assembly_ConstraintPointDistance.svg'
'line to be the same as the distance between another point\n'\ _tooltip = 'Add a "{}" to constrain the distance of two points in 2D or 3D.'
'and line.' _cstrFuncName = 'addPointsDistance'
@classmethod
def init(cls,obj):
points = [ info.Placement.multVec(info.Shape.Vertex1.Point)
for info in obj.Proxy.getElementsInfo() ]
obj.Distance = points[0].distanceToPoint(points[1])
class EqualAngle(Base2): class EqualAngle(Base2):
@ -1225,13 +1291,6 @@ class LineVertical(Base2):
_tooltip='Add a "{}" constraint to make a line segment vertical when\n'\ _tooltip='Add a "{}" constraint to make a line segment vertical when\n'\
'projected onto a plane.' 'projected onto a plane.'
class PointOnCircle(Base2):
_id = 26
_entityDef = (_p,_c)
_iconName = 'Assembly_ConstraintPointOnCircle.svg'
_tooltip='Add a "{}" to constrain a point on to a clyndrical plane\n' \
'defined by a cricle.'
class ArcLineTangent(Base2): class ArcLineTangent(Base2):
_id = 30 _id = 30
@ -1241,17 +1300,11 @@ class ArcLineTangent(Base2):
_tooltip='Add a "{}" constraint to make a line tangent to an arc\n'\ _tooltip='Add a "{}" constraint to make a line tangent to an arc\n'\
'at the start or end point of the arc.' 'at the start or end point of the arc.'
class Colinear(Base2):
_id = 39
_entityDef = (_lna, _lna)
_workplane = True
_iconName = 'Assembly_ConstraintColinear.svg'
_tooltip='Add a "{}" constraint to make to line colinear'
class BaseSketch(Base): class BaseSketch(Base):
_id = -1 _id = -1
_toolbarName = 'Assembly3 Sketch Constraints' _toolbarName = 'Assembly3 Sketch Constraints'
_toolbarVisible = False
class SketchPlane(BaseSketch): class SketchPlane(BaseSketch):
@ -1313,15 +1366,14 @@ class LineLength(BaseSketch):
@classmethod @classmethod
def prepare(cls,obj,solver): def prepare(cls,obj,solver):
func = PointsDistance.constraintFunc(obj,solver) func = cls.constraintFunc(obj,solver,'addPointsDistance')
if func: if not func:
return
_,p0,p1 = cls.getEntities(obj,solver,retAll=True)[0] _,p0,p1 = cls.getEntities(obj,solver,retAll=True)[0]
params = cls.getPropertyValues(obj) + [p0,p1] params = cls.getPropertyValues(obj) + [p0,p1]
ret = func(*params,group=solver.group) ret = func(*params,group=solver.group)
solver.system.log('{}: {}'.format(cstrName(obj),ret)) solver.system.log('{}: {}'.format(cstrName(obj),ret))
return ret return ret
else:
logger.warn('{} no constraint func'.format(cstrName(obj)))
class EqualLength(BaseDraftWire): class EqualLength(BaseDraftWire):
@ -1414,6 +1466,34 @@ class EqualRadius(BaseSketch):
raise RuntimeError('Constraint "{}" requires at least one ' raise RuntimeError('Constraint "{}" requires at least one '
'Draft.Circle'.format(cls.getName())) 'Draft.Circle'.format(cls.getName()))
class PointsProjectDistance(BaseSketch):
_id = 6
_entityDef = (_p,_p,_l)
_props = ["Distance"]
_iconName = 'Assembly_ConstraintPointsProjectDistance.svg'
_tooltip = 'Add a "{}" to constrain the distance of two points\n' \
'projected on a line.'
class EqualPointLineDistance(BaseSketch):
_id = 13
_entityDef = (_p,_l,_p,_l)
_workplane = True
_iconName = 'Assembly_ConstraintEqualPointLineDistance.svg'
_tooltip='Add a "{}" to constrain the distance between a point and a\n'\
'line to be the same as the distance between another point\n'\
'and line.'
class Colinear(BaseSketch):
_id = 39
_entityDef = (_lna, _lna)
_workplane = True
_iconName = 'Assembly_ConstraintColinear.svg'
_tooltip='Add a "{}" constraint to make to line colinear'
# class CubicLineTangent(BaseSketch): # class CubicLineTangent(BaseSketch):
# _id = 31 # _id = 31
# #

50
gui.py
View File

@ -118,10 +118,41 @@ class SelectionObserver:
class AsmCmdManager(ProxyType): class AsmCmdManager(ProxyType):
_HiddenToolbars = set()
Toolbars = OrderedDict() Toolbars = OrderedDict()
Menus = OrderedDict() Menus = OrderedDict()
_defaultMenuGroupName = '&Assembly3' _defaultMenuGroupName = '&Assembly3'
@staticmethod
def getToolbarParams():
return FreeCAD.ParamGet('User parameter:BaseApp/MainWindow/Toolbars')
@classmethod
def init(mcs):
if not mcs.getParam('Bool','GuiInited',False):
hgrp = mcs.getToolbarParams()
for toolbar in mcs._HiddenToolbars:
hgrp.SetBool(toolbar,False)
mcs.setParam('Bool','GuiInited',True)
@classmethod
def toggleToolbars(mcs):
hgrp = mcs.getToolbarParams()
show = False
for toolbar in mcs._HiddenToolbars:
if not hgrp.GetBool(toolbar,True):
show = True
break
from PySide import QtGui
mw = FreeCADGui.getMainWindow()
for toolbar in mcs._HiddenToolbars:
if show != hgrp.GetBool(toolbar,True):
hgrp.SetBool(toolbar,show)
tb = mw.findChild(QtGui.QToolBar,toolbar)
if not tb:
logger.error('cannot find toolbar "{}"'.format(toolbar))
tb.setVisible(show)
@classmethod @classmethod
def register(mcs,cls): def register(mcs,cls):
if cls._id < 0: if cls._id < 0:
@ -129,22 +160,29 @@ class AsmCmdManager(ProxyType):
super(AsmCmdManager,mcs).register(cls) super(AsmCmdManager,mcs).register(cls)
FreeCADGui.addCommand(cls.getName(),cls) FreeCADGui.addCommand(cls.getName(),cls)
if cls._toolbarName: if cls._toolbarName:
mcs.Toolbars.setdefault(cls._toolbarName,[]).append(cls) tb = mcs.Toolbars.setdefault(cls._toolbarName,[])
if not tb and not getattr(cls,'_toolbarVisible',True):
mcs._HiddenToolbars.add(cls._toolbarName)
tb.append(cls)
if cls._menuGroupName is not None: if cls._menuGroupName is not None:
name = cls._menuGroupName name = cls._menuGroupName
if not name: if not name:
name = mcs._defaultMenuGroupName name = mcs._defaultMenuGroupName
mcs.Menus.setdefault(name,[]).append(cls) mcs.Menus.setdefault(name,[]).append(cls)
def getParamGroup(cls): @classmethod
def getParamGroup(mcs):
return FreeCAD.ParamGet( return FreeCAD.ParamGet(
'User parameter:BaseApp/Preferences/Mod/Assembly3') 'User parameter:BaseApp/Preferences/Mod/Assembly3')
def getParam(cls,tp,name,default=None): @classmethod
return getattr(cls.getParamGroup(),'Get'+tp)(name,default) def getParam(mcs,tp,name,default=None):
return getattr(mcs.getParamGroup(),'Get'+tp)(name,default)
def setParam(cls,tp,name,v): @classmethod
getattr(cls.getParamGroup(),'Set'+tp)(name,v) def setParam(mcs,tp,name,v):
getattr(mcs.getParamGroup(),'Set'+tp)(name,v)
def workbenchActivated(cls): def workbenchActivated(cls):
pass pass

View File

@ -39,6 +39,7 @@ class Assembly3Workbench(FreeCADGui.Workbench):
def Initialize(self): def Initialize(self):
from .mover import AsmDocumentObserver from .mover import AsmDocumentObserver
from .gui import AsmCmdManager from .gui import AsmCmdManager
AsmCmdManager.init()
cmdSet = set() cmdSet = set()
for name,cmds in AsmCmdManager.Toolbars.items(): for name,cmds in AsmCmdManager.Toolbars.items():
cmdSet.update(cmds) cmdSet.update(cmds)