ShowWB: fix header uniformity
Make headers uniform + remote trailing whitespace
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2018 *
|
||||
# * Copyright (c) 2018 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -27,24 +26,24 @@ class Container(object):
|
||||
"""Container class: a unified interface for container objects, such as Group, Part, Body, or Document.
|
||||
This is a temporary implementation."""
|
||||
Object = None #DocumentObject or Document, the actual container
|
||||
|
||||
|
||||
def __init__(self, obj):
|
||||
self.Object = obj
|
||||
|
||||
|
||||
def self_check(self):
|
||||
if self.Object is None:
|
||||
raise ValueError("Null!")
|
||||
if not isAContainer(self.Object, links_too= True):
|
||||
raise NotAContainerError(self.Object)
|
||||
|
||||
|
||||
def getAllChildren(self):
|
||||
"""Returns all objects directly contained by the container. all = static + dynamic."""
|
||||
return self.getStaticChildren() + self.getDynamicChildren()
|
||||
|
||||
|
||||
def getStaticChildren(self):
|
||||
"""Returns children tightly bound to the container, such as Origin. The key thing
|
||||
"""Returns children tightly bound to the container, such as Origin. The key thing
|
||||
about them is that they are not supposed to be removed or added from/to the container."""
|
||||
|
||||
|
||||
self.self_check()
|
||||
container = self.Object
|
||||
if container.isDerivedFrom('App::Document'):
|
||||
@@ -66,7 +65,7 @@ class Container(object):
|
||||
"""Returns dynamic children, i.e. the stuff that can be removed from the container."""
|
||||
self.self_check()
|
||||
container = self.Object
|
||||
|
||||
|
||||
if container.isDerivedFrom('App::Document'):
|
||||
# find all objects not contained by any Part or Body
|
||||
result = set(container.Objects)
|
||||
@@ -92,28 +91,28 @@ class Container(object):
|
||||
return result
|
||||
|
||||
raise RuntimeError("getDynamicChildren: unexpected container type!")
|
||||
|
||||
|
||||
def isACS(self):
|
||||
"""isACS(): returns true if the container forms internal coordinate system."""
|
||||
self.self_check()
|
||||
container = self.Object
|
||||
|
||||
|
||||
if container.isDerivedFrom('App::Document'):
|
||||
return True #Document is a special thing... is it a CS or not is a matter of coding convenience.
|
||||
return True #Document is a special thing... is it a CS or not is a matter of coding convenience.
|
||||
elif container.hasExtension('App::GeoFeatureGroupExtension'):
|
||||
return True
|
||||
elif container.hasChildElement(): # Link
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def isAVisGroup(self):
|
||||
"""isAVisGroup(): returns True if the container consumes viewproviders of children, and thus affects their visibility."""
|
||||
self.self_check()
|
||||
container = self.Object
|
||||
|
||||
|
||||
if container.isDerivedFrom('App::Document'):
|
||||
return True #Document is a special thing... Return value is a matter of coding convenience.
|
||||
return True #Document is a special thing... Return value is a matter of coding convenience.
|
||||
elif container.hasExtension('App::GeoFeatureGroupExtension'):
|
||||
return True
|
||||
elif container.isDerivedFrom('App::Origin'):
|
||||
@@ -122,7 +121,7 @@ class Container(object):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def getCSChildren(self):
|
||||
if not self.isACS():
|
||||
raise TypeError("Container is not a coordinate system")
|
||||
@@ -148,22 +147,22 @@ class Container(object):
|
||||
def hasObject(self, obj):
|
||||
"""Returns True if the container contains specified object directly."""
|
||||
return obj in self.getAllChildren()
|
||||
|
||||
|
||||
def hasObjectRecursive(self, obj):
|
||||
return self.Object in ContainerChain(obj)
|
||||
|
||||
def _getMetacontainerChildren(container, isrightcontainer_func):
|
||||
"""Gathers up children of metacontainer - a container structure formed by containers of specific type.
|
||||
"""Gathers up children of metacontainer - a container structure formed by containers of specific type.
|
||||
For example, coordinate systems form a kind of container structure.
|
||||
|
||||
|
||||
container: instance of Container class
|
||||
isrightcontainer_func: a function f(cnt)->bool, where cnt is a Container object."""
|
||||
|
||||
|
||||
result = []
|
||||
list_traversing_now = [container] #list of Container instances
|
||||
list_to_be_traversed_next = [] #list of Container instances
|
||||
visited_containers = set([container.Object]) #set of DocumentObjects
|
||||
|
||||
|
||||
while len(list_traversing_now) > 0:
|
||||
list_to_be_traversed_next = []
|
||||
for itcnt in list_traversing_now:
|
||||
@@ -175,19 +174,19 @@ def _getMetacontainerChildren(container, isrightcontainer_func):
|
||||
if not isrightcontainer_func(newcnt):
|
||||
list_to_be_traversed_next.append(newcnt)
|
||||
list_traversing_now = list_to_be_traversed_next
|
||||
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def isAContainer(obj, links_too = False):
|
||||
'''isAContainer(obj, links_too): returns True if obj is an object container, such as
|
||||
Group, Part, Body. The important characteristic of an object being a
|
||||
container is that it can be activated to receive new objects. Documents
|
||||
'''isAContainer(obj, links_too): returns True if obj is an object container, such as
|
||||
Group, Part, Body. The important characteristic of an object being a
|
||||
container is that it can be activated to receive new objects. Documents
|
||||
are considered containers, too.
|
||||
If links_too, App::Link objects are considered containers, too. Then, container tree
|
||||
If links_too, App::Link objects are considered containers, too. Then, container tree
|
||||
isn't necessarily a tree.'''
|
||||
|
||||
|
||||
if obj.isDerivedFrom('App::Document'):
|
||||
return True
|
||||
if obj.hasExtension('App::GroupExtension'):
|
||||
@@ -208,27 +207,27 @@ def ContainerOf(obj):
|
||||
if cnt is not None and dep is not cnt:
|
||||
raise ContainerTreeError("Container tree is not a tree")
|
||||
cnt = dep
|
||||
if cnt is None:
|
||||
if cnt is None:
|
||||
return obj.Document
|
||||
return cnt
|
||||
|
||||
|
||||
def getVisGroupOf(obj):
|
||||
chain = VisGroupChain(obj)
|
||||
return chain[-1]
|
||||
|
||||
#from Part-o-magic... over-engineered, but proven to work
|
||||
def ContainerChain(feat):
|
||||
'''ContainerChain(feat): container path to feat (not including feat itself).
|
||||
Last container directly contains the feature.
|
||||
'''ContainerChain(feat): container path to feat (not including feat itself).
|
||||
Last container directly contains the feature.
|
||||
Example of output: [<document>,<SuperPart>,<Part>,<Body>]'''
|
||||
|
||||
|
||||
if feat.isDerivedFrom('App::Document'):
|
||||
return []
|
||||
|
||||
|
||||
list_traversing_now = [feat]
|
||||
set_of_deps = set()
|
||||
list_of_deps = []
|
||||
|
||||
|
||||
while len(list_traversing_now) > 0:
|
||||
list_to_be_traversed_next = []
|
||||
for feat in list_traversing_now:
|
||||
@@ -241,7 +240,7 @@ def ContainerChain(feat):
|
||||
if len(list_to_be_traversed_next) > 1:
|
||||
raise ContainerTreeError("Container tree is not a tree")
|
||||
list_traversing_now = list_to_be_traversed_next
|
||||
|
||||
|
||||
return [feat.Document] + list_of_deps[::-1]
|
||||
|
||||
def CSChain(feat):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2016 *
|
||||
# * Copyright (c) 2016 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -22,13 +21,13 @@
|
||||
# ***************************************************************************/
|
||||
|
||||
def getAllDependencies(feat):
|
||||
'''getAllDependencies(feat): gets all features feat depends on, directly or indirectly.
|
||||
Returns a list, with deepest dependencies last. feat is not included in the list, except
|
||||
'''getAllDependencies(feat): gets all features feat depends on, directly or indirectly.
|
||||
Returns a list, with deepest dependencies last. feat is not included in the list, except
|
||||
if the feature depends on itself (dependency loop).'''
|
||||
list_traversing_now = [feat]
|
||||
set_of_deps = set()
|
||||
list_of_deps = []
|
||||
|
||||
|
||||
while len(list_traversing_now) > 0:
|
||||
list_to_be_traversed_next = []
|
||||
for feat in list_traversing_now:
|
||||
@@ -37,19 +36,19 @@ def getAllDependencies(feat):
|
||||
set_of_deps.add(dep)
|
||||
list_of_deps.append(dep)
|
||||
list_to_be_traversed_next.append(dep)
|
||||
|
||||
|
||||
list_traversing_now = list_to_be_traversed_next
|
||||
|
||||
|
||||
return list_of_deps
|
||||
|
||||
def getAllDependent(feat):
|
||||
'''getAllDependent(feat): gets all features that depend on feat, directly or indirectly.
|
||||
Returns a list, with deepest dependencies last. feat is not included in the list, except
|
||||
'''getAllDependent(feat): gets all features that depend on feat, directly or indirectly.
|
||||
Returns a list, with deepest dependencies last. feat is not included in the list, except
|
||||
if the feature depends on itself (dependency loop).'''
|
||||
list_traversing_now = [feat]
|
||||
set_of_deps = set()
|
||||
list_of_deps = []
|
||||
|
||||
|
||||
while len(list_traversing_now) > 0:
|
||||
list_to_be_traversed_next = []
|
||||
for feat in list_traversing_now:
|
||||
@@ -58,7 +57,7 @@ def getAllDependent(feat):
|
||||
set_of_deps.add(dep)
|
||||
list_of_deps.append(dep)
|
||||
list_to_be_traversed_next.append(dep)
|
||||
|
||||
|
||||
list_traversing_now = list_to_be_traversed_next
|
||||
|
||||
|
||||
return list_of_deps
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -25,7 +24,7 @@ class SceneDetail(object):
|
||||
"""SceneDetail class: abstract class for tempovis scene save/restore plug-in. An implementation must provide:
|
||||
* data storage (as "data" attribute of the object)
|
||||
* constructor (preferably, with value for stored data as optional argument)
|
||||
* methods to apply values to actual scene (apply_data),
|
||||
* methods to apply values to actual scene (apply_data),
|
||||
* ...and to read out the state of the detail in the actual scene (scene_value)
|
||||
* keying, for identifying two detail instances that affect the exact same thing
|
||||
* class_id string, which is required for keying
|
||||
@@ -34,30 +33,30 @@ class SceneDetail(object):
|
||||
* info on if the modification affects what is saved to disk, and thus should be undone temporarily for file writing.
|
||||
"""
|
||||
class_id = ''
|
||||
|
||||
|
||||
data = None
|
||||
doc = None
|
||||
|
||||
## Storage field for TV. Mild restore means that the saved state won't be restored
|
||||
# if the current state differs from the state requested via last TempoVis.modify(...) call.
|
||||
# This is a default, it may be changed per-instance.
|
||||
mild_restore = False
|
||||
|
||||
|
||||
## Storage field for TV. Mild restore means that the saved state won't be restored
|
||||
# if the current state differs from the state requested via last TempoVis.modify(...) call.
|
||||
# This is a default, it may be changed per-instance.
|
||||
mild_restore = False
|
||||
|
||||
def set_doc(self, doc):
|
||||
self.doc = doc
|
||||
|
||||
|
||||
# <interface>
|
||||
key = None #a string or something alike to use to store/find the entry in TempoVis. For example, a string "{object_name}.{property_name}".
|
||||
key = None #a string or something alike to use to store/find the entry in TempoVis. For example, a string "{object_name}.{property_name}".
|
||||
affects_persistence = False #True indicate that the changes will be recorded if the doc is saved, and that this detail should be restored for saving
|
||||
|
||||
|
||||
def scene_value(self):
|
||||
"""scene_value(): returns the value from the scene"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def apply_data(self, val):
|
||||
"""apply a value to scene"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
## Equality test. Override if data attributes can't be directly compared
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
@@ -66,13 +65,12 @@ class SceneDetail(object):
|
||||
raise TypeError('{self} can\'t be compared with {other}'
|
||||
.format(self= repr(self), other= repr(other)))
|
||||
# </interface>
|
||||
|
||||
|
||||
# <utility>
|
||||
@property
|
||||
def full_key(self):
|
||||
return (self.class_id, self.doc.Name if self.doc else None, self.key)
|
||||
|
||||
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -28,11 +27,11 @@ import FreeCADGui
|
||||
class Camera(SceneDetail):
|
||||
"""Camera(doc): TempoVis plugin for saving and restoring camera."""
|
||||
class_id = 'SDCamera'
|
||||
|
||||
|
||||
def __init__(self, doc):
|
||||
self.doc = doc
|
||||
self.key = 'the_cam'
|
||||
|
||||
|
||||
def _viewer(self):
|
||||
gdoc = FreeCADGui.getDocument(self.doc.Name)
|
||||
v = gdoc.activeView()
|
||||
@@ -42,7 +41,7 @@ class Camera(SceneDetail):
|
||||
|
||||
def scene_value(self):
|
||||
return self._viewer().getCamera()
|
||||
|
||||
|
||||
def apply_data(self, val):
|
||||
self._viewer().setCamera(val)
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -28,12 +27,12 @@ import FreeCADGui as Gui
|
||||
class ClipPlane(SceneDetail):
|
||||
"""ClipPlane(document, enable = None, placement = None, offset = 0.0):
|
||||
TempoVis plugin for applying clipping plane to whole project except edit root.
|
||||
enable can be 0 for disable, 1 for enable, and -1 for toggle
|
||||
enable can be 0 for disable, 1 for enable, and -1 for toggle
|
||||
(FIXME: toggle value support is a hack for while we can't read out the current state)."""
|
||||
|
||||
|
||||
class_id = 'SDClipPlane'
|
||||
key = ''
|
||||
|
||||
|
||||
def __init__(self, document, enable = None, placement = None, offset = 0.0):
|
||||
self.doc = document
|
||||
if enable is not None:
|
||||
@@ -42,10 +41,10 @@ class ClipPlane(SceneDetail):
|
||||
dir = placement.Rotation.multVec(App.Vector(0,0,1))
|
||||
placement.Base = placement.Base + dir*offset
|
||||
self.data = (enable, placement)
|
||||
|
||||
|
||||
def scene_value(self):
|
||||
return (0, None) #hack. For until there is a way to easily query the plane, this should be good enough.
|
||||
|
||||
|
||||
def apply_data(self, val):
|
||||
enable, pla = val
|
||||
if enable != 0:
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -31,14 +30,14 @@ class ObjectClipPlane(SceneDetail):
|
||||
class_id = 'SDObjectClipPlane'
|
||||
propname = ''
|
||||
objname = ''
|
||||
|
||||
|
||||
def __init__(self, object, enable = None, placement = None, offset = 0.0):
|
||||
self.objname = object.Name
|
||||
self.doc = object.Document
|
||||
self.key = self.objname
|
||||
self.key = self.objname
|
||||
if enable is not None:
|
||||
self.data = self.val(enable, placement, offset)
|
||||
|
||||
|
||||
def scene_value(self):
|
||||
vp = self.doc.getObject(self.objname).ViewObject
|
||||
cp = getClipPlaneNode(vp, make_if_missing= False)
|
||||
@@ -50,7 +49,7 @@ class ObjectClipPlane(SceneDetail):
|
||||
D = pln.getDistanceFromOrigin()
|
||||
normal = tuple(pln.getNormal())
|
||||
return enable, (normal, D)
|
||||
|
||||
|
||||
def apply_data(self, val):
|
||||
enable, pldef = val
|
||||
vp = self.doc.getObject(self.objname).ViewObject
|
||||
@@ -62,12 +61,12 @@ class ObjectClipPlane(SceneDetail):
|
||||
v, d = pldef
|
||||
cp.plane.setValue(coin.SbPlane(coin.SbVec3f(*v), d))
|
||||
cp.on.setValue(enable)
|
||||
|
||||
|
||||
def val(self, enable, placement = None, offset = 0.0):
|
||||
"""val(enable, placement = None, offset = 0.0): constructs a value from convenient
|
||||
parameters. Placement is in global CS. The cutting will be by XY plane of Placement;
|
||||
"""val(enable, placement = None, offset = 0.0): constructs a value from convenient
|
||||
parameters. Placement is in global CS. The cutting will be by XY plane of Placement;
|
||||
the stuff in negative Z is visible and the stuff in positive Z is invisible."""
|
||||
|
||||
|
||||
pldef = None
|
||||
if enable:
|
||||
obj = self.doc.getObject(self.objname)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -24,7 +23,7 @@
|
||||
from Show.SceneDetail import SceneDetail
|
||||
|
||||
class Pickability(SceneDetail):
|
||||
"""Pickability(object, pickstyle = None):Plugin for TempoVis for altering pick style
|
||||
"""Pickability(object, pickstyle = None):Plugin for TempoVis for altering pick style
|
||||
of objects (i.e., selectability).
|
||||
pickstyle may be:
|
||||
PS_REGULAR = 0 # selectable
|
||||
@@ -33,17 +32,17 @@ class Pickability(SceneDetail):
|
||||
class_id = 'SDPickability'
|
||||
propname = ''
|
||||
objname = ''
|
||||
|
||||
|
||||
def __init__(self, object, pickstyle = None):
|
||||
self.objname = object.Name
|
||||
self.doc = object.Document
|
||||
self.key = self.objname
|
||||
self.key = self.objname
|
||||
if pickstyle is not None:
|
||||
self.data = pickstyle
|
||||
|
||||
|
||||
def scene_value(self):
|
||||
return getPickStyle(self.doc.getObject(self.objname).ViewObject)
|
||||
|
||||
|
||||
def apply_data(self, val):
|
||||
setPickStyle(self.doc.getObject(self.objname).ViewObject, val)
|
||||
|
||||
@@ -65,7 +64,7 @@ def getPickStyleNode(viewprovider, make_if_missing = True):
|
||||
pick_style.style.setValue(coin.SoPickStyle.SHAPE)
|
||||
viewprovider.RootNode.insertChild(pick_style, 0)
|
||||
return pick_style
|
||||
|
||||
|
||||
|
||||
def getPickStyle(viewprovider):
|
||||
ps = getPickStyleNode(viewprovider, make_if_missing= False)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -25,13 +24,13 @@ from Show.SceneDetail import SceneDetail
|
||||
|
||||
class VProperty(SceneDetail):
|
||||
"""VProperty(object, propname, val = None): plugin for TempoVis to alter ViewProvider properties"""
|
||||
|
||||
|
||||
class_id = 'SDVProperty'
|
||||
affects_persistence = True
|
||||
propname = ''
|
||||
objname = ''
|
||||
mild_restore = True
|
||||
|
||||
|
||||
def __init__(self, object, propname, val = None):
|
||||
self.objname = object.Name
|
||||
self.propname = propname
|
||||
@@ -40,9 +39,9 @@ class VProperty(SceneDetail):
|
||||
self.data = val
|
||||
if propname == 'LinkVisibility': #seems to not be a property
|
||||
self.affects_persistence = False
|
||||
|
||||
|
||||
def scene_value(self):
|
||||
return getattr(self.doc.getObject(self.objname).ViewObject, self.propname)
|
||||
|
||||
|
||||
def apply_data(self, val):
|
||||
setattr(self.doc.getObject(self.objname).ViewObject, self.propname, val)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -26,19 +25,19 @@ from Show.SceneDetail import SceneDetail
|
||||
import FreeCADGui
|
||||
|
||||
class Workbench(SceneDetail):
|
||||
"""Workbench(wb = None): Plugin for TempoVis for changing active workbench.
|
||||
"""Workbench(wb = None): Plugin for TempoVis for changing active workbench.
|
||||
wb: string, a name of a workbench (e.g. 'SketcherWorkbench')"""
|
||||
class_id = 'SDWorkbench'
|
||||
mild_restore = True
|
||||
|
||||
|
||||
def __init__(self, wb = None):
|
||||
self.key = 'workbench'
|
||||
if wb is not None:
|
||||
self.data = wb
|
||||
|
||||
|
||||
def scene_value(self):
|
||||
return FreeCADGui.activeWorkbench().name()
|
||||
|
||||
|
||||
def apply_data(self, val):
|
||||
FreeCADGui.activateWorkbench(val)
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -20,11 +19,11 @@
|
||||
# * Suite 330, Boston, MA 02111-1307, USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
|
||||
def is3DObject(obj):
|
||||
"""is3DObject(obj): tests if the object has some 3d geometry.
|
||||
"""is3DObject(obj): tests if the object has some 3d geometry.
|
||||
TempoVis is made only for objects in 3d view, so all objects that don't pass this check are ignored by TempoVis."""
|
||||
|
||||
|
||||
# See "Gui Problem Sketcher and TechDraw" https://forum.freecadweb.org/viewtopic.php?f=3&t=22797
|
||||
|
||||
# observation: all viewproviders have transform node, then a switch node. If that switch node contains something, the object has something in 3d view.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -26,18 +25,18 @@ import FreeCAD
|
||||
class TVObserver(object):
|
||||
def __init__(self):
|
||||
FreeCAD.addDocumentObserver(self)
|
||||
|
||||
|
||||
def stop(self):
|
||||
FreeCAD.removeDocumentObserver(self)
|
||||
|
||||
|
||||
def slotStartSaveDocument(self, doc, filepath):
|
||||
from . import TVStack
|
||||
TVStack._slotStartSaveDocument(doc)
|
||||
|
||||
|
||||
def slotFinishSaveDocument(self, doc, filepath):
|
||||
from . import TVStack
|
||||
TVStack._slotFinishSaveDocument(doc)
|
||||
|
||||
|
||||
def slotDeletedDocument(self, doc):
|
||||
from . import TVStack
|
||||
TVStack._slotDeletedDocument(doc)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * Copyright (c) 2019 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -29,7 +28,7 @@ class TVStack(object):
|
||||
index_LUT = None # Key = id(tempovis_instance). Value = index in the stack.
|
||||
stack = None #list of weakrefs to TV instances. Using weakrefs, so that TempoVis can self-destruct if forgotten.
|
||||
document = None
|
||||
|
||||
|
||||
_rewind_tv = None
|
||||
|
||||
def __init__(self, document):
|
||||
@@ -44,11 +43,11 @@ class TVStack(object):
|
||||
idtv = id(tv)
|
||||
ref = weakref.ref(tv, (lambda _, idtv=idtv, self=self : self._destruction(idtv)))
|
||||
self.stack.insert(index, ref)
|
||||
|
||||
|
||||
self.rebuild_index(index)
|
||||
|
||||
tv._inserted(self, index)
|
||||
|
||||
|
||||
def _destruction(self, idtv):
|
||||
# the tempovis itself is destroyed already. Purge it from the stack (it should have withdrawn itself, but just in case).
|
||||
try:
|
||||
@@ -60,7 +59,7 @@ class TVStack(object):
|
||||
self.stack.pop(index)
|
||||
self.index_LUT.pop(idtv)
|
||||
self.rebuild_index(index)
|
||||
|
||||
|
||||
def withdraw(self, tv):
|
||||
idtv = id(tv)
|
||||
index = self.index_LUT[idtv]
|
||||
@@ -68,21 +67,21 @@ class TVStack(object):
|
||||
self.index_LUT.pop(idtv)
|
||||
|
||||
self.rebuild_index(index)
|
||||
|
||||
|
||||
tv = ref()
|
||||
if tv:
|
||||
tv._withdrawn(self, index)
|
||||
|
||||
|
||||
def value_after(self, tv, detail):
|
||||
"""value_after(tv, detail): returns tuple (tv1, detail), or None.
|
||||
Here, tv1 is the tv that remembers the value, and detail is reference to recorded
|
||||
data in tv1. None is returned, if no TVs in the stack after the provided one have
|
||||
"""value_after(tv, detail): returns tuple (tv1, detail), or None.
|
||||
Here, tv1 is the tv that remembers the value, and detail is reference to recorded
|
||||
data in tv1. None is returned, if no TVs in the stack after the provided one have
|
||||
recorded a change to this detail.
|
||||
|
||||
tv can be None, then, the function returns the original value of the detail, or
|
||||
|
||||
tv can be None, then, the function returns the original value of the detail, or
|
||||
None, if the current value matches the original."""
|
||||
from . import mTempoVis
|
||||
|
||||
|
||||
index = self.index_LUT[id(tv)] if tv is not None else -1
|
||||
for tvref in self.stack[index + 1 : ]:
|
||||
tv = tvref()
|
||||
@@ -90,14 +89,14 @@ class TVStack(object):
|
||||
if tv.has(detail):
|
||||
return (tv, tv.data[detail.full_key])
|
||||
return None
|
||||
|
||||
|
||||
def rebuild_index(self, start = 0):
|
||||
if start == 0:
|
||||
self.index_LUT = {}
|
||||
for i in range(start, len(self.stack)):
|
||||
self.index_LUT[id(self.stack[i]())] = i
|
||||
|
||||
|
||||
|
||||
|
||||
def purge_dead(self):
|
||||
"""removes dead TV instances from the stack"""
|
||||
n = 0
|
||||
@@ -108,18 +107,18 @@ class TVStack(object):
|
||||
if n > 0:
|
||||
self.rebuild_index()
|
||||
return n
|
||||
|
||||
|
||||
def dissolve(self):
|
||||
"""silently cleans all TVs, so that they won't restore."""
|
||||
for ref in self.stack:
|
||||
if ref() is not None:
|
||||
ref().forget()
|
||||
|
||||
|
||||
def unwindForSaving(self):
|
||||
from . import mTempoVis
|
||||
|
||||
self.rewindAfterSaving() #just in case there was a failed save before.
|
||||
|
||||
|
||||
details = {} #dict of detail original values. Key = detail key; value = detail instance with data representing the original value
|
||||
for ref in self.stack:
|
||||
tv = ref()
|
||||
@@ -127,26 +126,26 @@ class TVStack(object):
|
||||
if not key in details:
|
||||
if detail.affects_persistence:
|
||||
details[detail.full_key] = detail
|
||||
|
||||
|
||||
self._rewind_tv = mTempoVis.TempoVis(self.document, None)
|
||||
for key, detail in details.items():
|
||||
self._rewind_tv.modify(detail)
|
||||
|
||||
|
||||
def rewindAfterSaving(self):
|
||||
if self._rewind_tv is not None:
|
||||
self._rewind_tv.restore()
|
||||
self._rewind_tv = None
|
||||
|
||||
|
||||
def getSplitSequence(self, tv):
|
||||
"""getSplitSequence(tv): returns (list_before, list_after), neither list includes tv."""
|
||||
index = self.index_LUT[id(tv)]
|
||||
def deref(lst):
|
||||
def deref(lst):
|
||||
return [ref() for ref in lst]
|
||||
return deref(self.stack[0:index]), deref(self.stack[index+1:])
|
||||
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.stack[index]()
|
||||
|
||||
|
||||
def __len__(self):
|
||||
return len(self.stack)
|
||||
|
||||
@@ -157,23 +156,23 @@ class TVStack(object):
|
||||
def __reversed__(self):
|
||||
for ref in reversed(self.stack):
|
||||
yield ref()
|
||||
|
||||
|
||||
def restoreAll(self):
|
||||
for ref in reversed(self.stack):
|
||||
ref().restore()
|
||||
|
||||
|
||||
def byTag(self, tag):
|
||||
return [ref() for ref in self.stack if ref().tag == tag]
|
||||
|
||||
|
||||
|
||||
def mainStack(document, create_if_missing = True):
|
||||
"""mainStack(document, create_if_missing = True):returns the main TVStack instance for provided document"""
|
||||
docname = document.Name
|
||||
|
||||
|
||||
if create_if_missing:
|
||||
if not docname in global_stacks:
|
||||
global_stacks[docname] = TVStack(document)
|
||||
|
||||
|
||||
return global_stacks.get(docname, None)
|
||||
|
||||
def _slotDeletedDocument(document):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2016 *
|
||||
# * Copyright (c) 2016 Victor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
@@ -21,7 +20,7 @@
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
# module is named mTempoVis, because Show.TimpoVis exposes the class as its member, and hides the module TempoVis.py.
|
||||
# module is named mTempoVis, because Show.TimpoVis exposes the class as its member, and hides the module TempoVis.py
|
||||
|
||||
from . import Containers
|
||||
|
||||
@@ -37,7 +36,7 @@ Log = lambda msg: App.Console.PrintLog(msg + "\n")
|
||||
from copy import copy
|
||||
|
||||
S_EMPTY = 0 # TV is initialized, but no changes were done through it
|
||||
S_ACTIVE = 1 # TV has something to be undone
|
||||
S_ACTIVE = 1 # TV has something to be undone
|
||||
S_RESTORED = 2 # TV has been restored
|
||||
S_INTERNAL = 3 # TV instance is being used by another TV instance as a redo data storage
|
||||
|
||||
@@ -61,15 +60,15 @@ class TempoVis(object):
|
||||
then restoring all visibilities after editing.
|
||||
|
||||
Constructors:
|
||||
TempoVis(document, stack = MAINSTACK, **kwargs): creates a new TempoVis.
|
||||
|
||||
TempoVis(document, stack = MAINSTACK, **kwargs): creates a new TempoVis.
|
||||
|
||||
document: required. Objects not belonging to the document can't be modified via TempoVis.
|
||||
|
||||
|
||||
stack: optional. Which stack to insert this new TV into. Can be:
|
||||
a TVStack instance (then, the new TV is added to the top of the stack),
|
||||
MAINSTACK special value (a global stack for the document will be used), or
|
||||
a TVStack instance (then, the new TV is added to the top of the stack),
|
||||
MAINSTACK special value (a global stack for the document will be used), or
|
||||
None (then, the TV is not in any stack, and can be manually instertd into one if desired).
|
||||
|
||||
|
||||
Any additional keyword args are assigned as attributes. You can use it to immediately set a tag, for example.'''
|
||||
|
||||
document = None
|
||||
@@ -77,47 +76,47 @@ class TempoVis(object):
|
||||
|
||||
data = None # dict. key = ("class_id","key"), value = instance of SceneDetail
|
||||
data_requested = None #same as data, but stores (wanted) values passed to modify()
|
||||
|
||||
|
||||
state = S_EMPTY
|
||||
|
||||
|
||||
tag = '' #stores any user-defined string for identification purposes
|
||||
|
||||
def _init_attrs(self):
|
||||
'''initialize member variables to empty values (needed because we can't use mutable initial values when initializing member variables in class definition)'''
|
||||
self.data = {}
|
||||
self.data_requested = {}
|
||||
|
||||
|
||||
#<core interface>
|
||||
def __init__(self, document, stack = MAINSTACK, **kwargs):
|
||||
self._init_attrs()
|
||||
self.document = document
|
||||
|
||||
|
||||
if stack is MAINSTACK:
|
||||
stack = TVStack.mainStack(document)
|
||||
|
||||
|
||||
if stack is None:
|
||||
pass
|
||||
else:
|
||||
stack.insert(self)
|
||||
|
||||
|
||||
for key,val in kwargs.items():
|
||||
setattr(self, key, val)
|
||||
|
||||
|
||||
def __del__(self):
|
||||
if self.state == S_ACTIVE:
|
||||
self.restore(ultimate= True)
|
||||
|
||||
|
||||
def has(self, detail):
|
||||
'''has(self, detail): returns True if this TV has this detail value saved.
|
||||
example: tv.has(VProperty(obj, "Visibility"))'''
|
||||
return detail.full_key in self.data
|
||||
|
||||
|
||||
def stored_val(self, detail):
|
||||
'''stored_val(self, detail): returns value of detail remembered by this TV. If not, raises KeyError.'''
|
||||
return self.data[detail.full_key].data
|
||||
|
||||
def save(self, detail, mild_restore = False):
|
||||
'''save(detail, mild_restore = False):saves the scene detail to be restored.
|
||||
'''save(detail, mild_restore = False):saves the scene detail to be restored.
|
||||
The detail is saved only once; repeated calls are ignored.
|
||||
mild_restore: internal, do not use.'''
|
||||
self._change()
|
||||
@@ -133,36 +132,36 @@ class TempoVis(object):
|
||||
stored_dt.mild_restore = False
|
||||
|
||||
def modify(self, detail, mild_restore = None):
|
||||
'''modify(detail, mild_restore = True): modifies scene detail through this TV.
|
||||
'''modify(detail, mild_restore = True): modifies scene detail through this TV.
|
||||
The value is provided as an instance of SceneDetail implementation.
|
||||
The procedure takes care to account for the stack - that is, if in a TV applied
|
||||
later than this one this detail was changed too, the value saved therein is altered,
|
||||
The procedure takes care to account for the stack - that is, if in a TV applied
|
||||
later than this one this detail was changed too, the value saved therein is altered,
|
||||
rather than applied to the scene.
|
||||
|
||||
mild_restore: if True, when restoring later, checks if the value was changed
|
||||
|
||||
mild_restore: if True, when restoring later, checks if the value was changed
|
||||
by user after last call to modify(), and doesn't restore if it was changed.
|
||||
|
||||
|
||||
Example: tv.modify(VProperty(obj, "Visibility", True))'''
|
||||
|
||||
self._change()
|
||||
|
||||
|
||||
if mild_restore is not None:
|
||||
detail.mild_restore = mild_restore
|
||||
|
||||
|
||||
# save current
|
||||
self.save(detail, detail.mild_restore)
|
||||
|
||||
|
||||
# apply
|
||||
tv1, curr = self._value_after(detail)
|
||||
if tv1 is not None:
|
||||
tv1.data[detail.full_key].data = detail.data
|
||||
else:
|
||||
detail.apply_data(detail.data)
|
||||
|
||||
|
||||
# and record.
|
||||
if detail.mild_restore:
|
||||
self.data_requested[detail.full_key] = copy(detail)
|
||||
|
||||
|
||||
def restoreDetail(self, detail, ultimate = False):
|
||||
'''restoreDetail(detail, ultimate = False): restores a specific scene detail.
|
||||
ultimate: if true, the saved value is cleaned out.
|
||||
@@ -173,15 +172,15 @@ class TempoVis(object):
|
||||
self._restore_detail(detail)
|
||||
if ultimate:
|
||||
self.forgetDetail(detail)
|
||||
|
||||
|
||||
|
||||
|
||||
def forgetDetail(self, detail):
|
||||
'''forgetDetail(detail): ditches a saved detail value, making the change done through this TV permanent.'''
|
||||
self.data.pop(detail.full_key, None)
|
||||
self.data_requested.pop(detail.full_key, None)
|
||||
|
||||
|
||||
def forget(self):
|
||||
'''forget(self): clears this TV, making all changes done through it permanent.
|
||||
'''forget(self): clears this TV, making all changes done through it permanent.
|
||||
Also, withdraws the TV from the stack.'''
|
||||
self.state = S_EMPTY
|
||||
self.data = {}
|
||||
@@ -190,15 +189,15 @@ class TempoVis(object):
|
||||
|
||||
def restore(self, ultimate = True):
|
||||
'''restore(ultimate = True): undoes all changes done through this tempovis / restores saved scene details.
|
||||
ultimate: if true, the saved values are cleaned out, and the TV is withdrawn from
|
||||
ultimate: if true, the saved values are cleaned out, and the TV is withdrawn from
|
||||
the stack. If false, the TV will still remember stuff, and restore can be called again.
|
||||
'''
|
||||
if self.state == S_RESTORED:
|
||||
return
|
||||
|
||||
if self.state != S_INTERNAL and ultimate:
|
||||
self.state = S_RESTORED
|
||||
|
||||
self.state = S_RESTORED
|
||||
|
||||
for key, detail in self.data.items():
|
||||
try:
|
||||
self._restoreDetail(detail)
|
||||
@@ -209,9 +208,9 @@ class TempoVis(object):
|
||||
self.data = {}
|
||||
if self.is_in_stack:
|
||||
self.stack.withdraw(self)
|
||||
|
||||
|
||||
#</core interface>
|
||||
|
||||
|
||||
#<stack interface>
|
||||
def _inserted(self, stack, index):
|
||||
'''calles when this tv is inserted into a stack'''
|
||||
@@ -224,15 +223,15 @@ class TempoVis(object):
|
||||
return self.stack is not None
|
||||
#</stack interface>
|
||||
|
||||
#<convenience functions>
|
||||
#<convenience functions>
|
||||
def modifyVPProperty(self, doc_obj_or_list, prop_names, new_value = JUST_SAVE, mild_restore = None):
|
||||
'''modifyVPProperty(doc_obj_or_list, prop_names, new_value = JUST_SAVE, mild_restore = None): modifies
|
||||
prop_name property of ViewProvider of doc_obj_or_list, and remembers
|
||||
original value of the property. Original values will be restored upon
|
||||
TempoVis deletion, or call to restore().
|
||||
|
||||
|
||||
mild_restore: test if user changed the value manually when restoring the TV.'''
|
||||
|
||||
|
||||
if self.state == S_RESTORED:
|
||||
Wrn("Attempting to use a TV that has been restored. There must be a problem with code.")
|
||||
return
|
||||
@@ -264,7 +263,7 @@ class TempoVis(object):
|
||||
def restoreVPProperty(self, doc_obj_or_list, prop_names):
|
||||
'''restoreVPProperty(doc_obj_or_list, prop_name, new_value): restores specific property changes.'''
|
||||
from .SceneDetails.VProperty import VProperty
|
||||
|
||||
|
||||
if not hasattr(doc_obj_or_list, '__iter__'):
|
||||
doc_obj_or_list = [doc_obj_or_list]
|
||||
if not isinstance(prop_names,(tuple,list)):
|
||||
@@ -279,7 +278,7 @@ class TempoVis(object):
|
||||
|
||||
|
||||
def saveBodyVisibleFeature(self, doc_obj_or_list):
|
||||
"""saveBodyVisibleFeature(self, doc_obj_or_list): saves Visibility of currently
|
||||
"""saveBodyVisibleFeature(self, doc_obj_or_list): saves Visibility of currently
|
||||
visible feature, for every body of PartDesign features in the provided list."""
|
||||
if not hasattr(doc_obj_or_list, '__iter__'):
|
||||
doc_obj_or_list = [doc_obj_or_list]
|
||||
@@ -297,7 +296,7 @@ class TempoVis(object):
|
||||
return objs
|
||||
|
||||
def show(self, doc_obj_or_list, links_too = True, mild_restore = None):
|
||||
'''show(doc_obj_or_list, links_too = True): shows objects (sets their Visibility to True).
|
||||
'''show(doc_obj_or_list, links_too = True): shows objects (sets their Visibility to True).
|
||||
doc_obj_or_list can be a document object, or a list of document objects.
|
||||
If links_too is True, all Links of the objects are also hidden, by setting LinkVisibility attribute of each object.'''
|
||||
doc_obj_or_list = self._3D_objects(doc_obj_or_list)
|
||||
@@ -320,15 +319,15 @@ class TempoVis(object):
|
||||
from .Containers import isAContainer
|
||||
from .DepGraphTools import getAllDependencies, getAllDependent
|
||||
if subname:
|
||||
# a link-path was provided. doc_obj has nothing to do with the object we want
|
||||
# a link-path was provided. doc_obj has nothing to do with the object we want
|
||||
# to collect dependencies from. So, replace it with the one pointed by link-path.
|
||||
cnt_chain = doc_obj.getSubObjectList(subname)
|
||||
doc_obj = cnt_chain[-1].getLinkedObject()
|
||||
# cnt_chain can either end with the object (e.g. if a sketch is in a part, and
|
||||
# a link is to a part), or it may be a Link object (if we have a straight or
|
||||
# cnt_chain can either end with the object (e.g. if a sketch is in a part, and
|
||||
# a link is to a part), or it may be a Link object (if we have a straight or
|
||||
# even nested Link to the sketch).
|
||||
#
|
||||
# I don't know why do we need that isAContainer check here, but I'm leaving it,
|
||||
# I don't know why do we need that isAContainer check here, but I'm leaving it,
|
||||
# realthunder must be knowing his business --DeepSOIC
|
||||
cnt_chain = [ o for o in cnt_chain
|
||||
if o==cnt_chain[-1] or isAContainer(o, links_too= True) ]
|
||||
@@ -364,7 +363,7 @@ class TempoVis(object):
|
||||
self._change()
|
||||
from .SceneDetails.Camera import Camera
|
||||
self.save(Camera(self.document))
|
||||
|
||||
|
||||
def restoreCamera(self, ultimate = False):
|
||||
from .SceneDetails.Camera import Camera
|
||||
dt = Camera(self.document)
|
||||
@@ -373,17 +372,17 @@ class TempoVis(object):
|
||||
def setUnpickable(self, doc_obj_or_list, actual_pick_style = 2): #2 is coin.SoPickStyle.UNPICKABLE
|
||||
'''setUnpickable(doc_obj_or_list, actual_pick_style = 2): sets object unpickable (transparent to clicks).
|
||||
doc_obj_or_list: object or list of objects to alter (App)
|
||||
actual_pick_style: optional parameter, specifying the actual pick style:
|
||||
actual_pick_style: optional parameter, specifying the actual pick style:
|
||||
0 = regular, 1 = bounding box, 2 (default) = unpickable.
|
||||
|
||||
Implementation detail: uses SoPickStyle node. If viewprovider already has a node
|
||||
of this type as direct child, one is used. Otherwise, new one is created and
|
||||
inserted as the very first node, and remains there even after restore()/deleting
|
||||
|
||||
Implementation detail: uses SoPickStyle node. If viewprovider already has a node
|
||||
of this type as direct child, one is used. Otherwise, new one is created and
|
||||
inserted as the very first node, and remains there even after restore()/deleting
|
||||
tempovis. '''
|
||||
|
||||
|
||||
from .SceneDetails.Pickability import Pickability
|
||||
from .ShowUtils import is3DObject
|
||||
|
||||
|
||||
if not hasattr(doc_obj_or_list, '__iter__'):
|
||||
doc_obj_or_list = [doc_obj_or_list]
|
||||
for doc_obj in doc_obj_or_list:
|
||||
@@ -392,20 +391,20 @@ class TempoVis(object):
|
||||
dt = Pickability(doc_obj, actual_pick_style)
|
||||
self.modify(dt)
|
||||
|
||||
def clipPlane(self, doc_obj_or_list, enable, placement, offset = 0.02):
|
||||
def clipPlane(self, doc_obj_or_list, enable, placement, offset = 0.02):
|
||||
'''clipPlane(doc_obj_or_list, enable, placement, offset): slices off the object with a clipping plane.
|
||||
doc_obj_or_list: object or list of objects to alter (App)
|
||||
enable: True if you want clipping, False if you want to remove clipping:
|
||||
enable: True if you want clipping, False if you want to remove clipping:
|
||||
placement: XY plane of local coordinates of the placement is the clipping plane. The placement must be in document's global coordinate system.
|
||||
offset: shifts the plane. Positive offset reveals more of the object.
|
||||
|
||||
Implementation detail: uses SoClipPlane node. If viewprovider already has a node
|
||||
of this type as direct child, one is used. Otherwise, new one is created and
|
||||
|
||||
Implementation detail: uses SoClipPlane node. If viewprovider already has a node
|
||||
of this type as direct child, one is used. Otherwise, new one is created and
|
||||
inserted as the very first node. The node is left, but disabled when tempovis is restoring.'''
|
||||
|
||||
|
||||
from .SceneDetails.ObjectClipPlane import ObjectClipPlane
|
||||
from .ShowUtils import is3DObject
|
||||
|
||||
|
||||
if not hasattr(doc_obj_or_list, '__iter__'):
|
||||
doc_obj_or_list = [doc_obj_or_list]
|
||||
for doc_obj in doc_obj_or_list:
|
||||
@@ -413,14 +412,14 @@ class TempoVis(object):
|
||||
continue
|
||||
dt = ObjectClipPlane(doc_obj, enable, placement, offset)
|
||||
self.modify(dt)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def allVisibleObjects(aroundObject):
|
||||
'''allVisibleObjects(aroundObject): returns list of objects that have to be toggled invisible for only aroundObject to remain.
|
||||
'''allVisibleObjects(aroundObject): returns list of objects that have to be toggled invisible for only aroundObject to remain.
|
||||
If a whole container can be made invisible, it is returned, instead of its child objects.'''
|
||||
from .ShowUtils import is3DObject
|
||||
from . import Containers
|
||||
|
||||
|
||||
chain = Containers.VisGroupChain(aroundObject)
|
||||
result = []
|
||||
for i in range(len(chain)):
|
||||
@@ -434,13 +433,13 @@ class TempoVis(object):
|
||||
if container.isChildVisible(obj):
|
||||
result.append(obj)
|
||||
return result
|
||||
|
||||
|
||||
def sketchClipPlane(self, sketch, enable = None, reverted = False):
|
||||
'''sketchClipPlane(sketch, enable = None): Clips all objects by plane of sketch.
|
||||
'''sketchClipPlane(sketch, enable = None): Clips all objects by plane of sketch.
|
||||
If enable argument is omitted, calling the routine repeatedly will toggle clipping plane.'''
|
||||
|
||||
|
||||
from .SceneDetails.ClipPlane import ClipPlane
|
||||
|
||||
|
||||
editDoc = Gui.editDocument()
|
||||
if editDoc is None:
|
||||
doc = sketch.Document
|
||||
@@ -457,14 +456,14 @@ class TempoVis(object):
|
||||
|
||||
if enable: # clip plane shall be disabled so new placement can be applied
|
||||
self.modify(ClipPlane(doc, 0))
|
||||
|
||||
|
||||
self.modify(ClipPlane(doc, toggle, pla, 0.02))
|
||||
sketch.ViewObject.SectionView = enable if enable is not None else not sketch.ViewObject.SectionView
|
||||
|
||||
|
||||
def activateWorkbench(self, wb_name):
|
||||
from .SceneDetails.Workbench import Workbench
|
||||
self.modify(Workbench(wb_name))
|
||||
|
||||
|
||||
#</convenience functions>
|
||||
|
||||
#<internals>
|
||||
@@ -482,7 +481,7 @@ class TempoVis(object):
|
||||
else:
|
||||
#modify saved detail of higher TV
|
||||
tv1.data[detail.full_key].data = p.data
|
||||
|
||||
|
||||
def _purge_milds(self, detail):
|
||||
"""_purge_milds(detail): wipes out detail from earlier TVs if the detail is mild-restore."""
|
||||
if not self.is_in_stack:
|
||||
@@ -502,13 +501,13 @@ class TempoVis(object):
|
||||
self.state = S_ACTIVE
|
||||
if self.state == S_RESTORED:
|
||||
Wrn("Attempting to use a TV that has been restored. There must be a problem with code.")
|
||||
self.tv_redo = None
|
||||
self.tv_redo = None
|
||||
|
||||
def _value_after(self, detail, query_scene = False):
|
||||
'''_value_current(detail): returns (tv, detail1). SceneDetail instance holds "current" value of
|
||||
scene detail (current from the context of this TV; i.e. either the current scene
|
||||
'''_value_current(detail): returns (tv, detail1). SceneDetail instance holds "current" value of
|
||||
scene detail (current from the context of this TV; i.e. either the current scene
|
||||
status, or the saved state from upper TVs).
|
||||
If no upper TV has saved the detail value, returns either (None, None), or
|
||||
If no upper TV has saved the detail value, returns either (None, None), or
|
||||
(None, detail1) if query_scene is True, where detail1 holds value from the scene.'''
|
||||
def scene_value():
|
||||
if query_scene:
|
||||
@@ -517,7 +516,7 @@ class TempoVis(object):
|
||||
return (None, cpy)
|
||||
else:
|
||||
return (None, None)
|
||||
|
||||
|
||||
if self.is_in_stack:
|
||||
va = self.stack.value_after(self, detail)
|
||||
if va is None:
|
||||
@@ -526,20 +525,18 @@ class TempoVis(object):
|
||||
return va
|
||||
else:
|
||||
return scene_value()
|
||||
|
||||
|
||||
def _3D_objects(self, doc_obj_or_list):
|
||||
"""_3D_objects(doc_obj_or_list): returns list of objects that are in 3d view."""
|
||||
from .ShowUtils import is3DObject
|
||||
|
||||
|
||||
if not hasattr(doc_obj_or_list, '__iter__'):
|
||||
doc_obj_or_list = [doc_obj_or_list]
|
||||
|
||||
|
||||
return [obj for obj in doc_obj_or_list if is3DObject(obj)]
|
||||
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
|
||||
def __setstate__(self, state):
|
||||
self._init_attrs()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user