Show: Tempovis stack support
Improvents: * Allows using several tempovis instances in arbitrary order * plugin system (SceneDetail), ease of extending * Mild restore feature - more respect for changes made by user * workbench switching support * undo saveable changes for the time of writing a file Regressions: * Removed support for pickling (with hopes to reintroduce later)
This commit is contained in:
committed by
Yorik van Havre
parent
f29765ff7b
commit
a09b83ec0d
48
src/Mod/Show/SceneDetails/Camera.py
Normal file
48
src/Mod/Show/SceneDetails/Camera.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This library is free software; you can redistribute it and/or *
|
||||
# * modify it under the terms of the GNU Library General Public *
|
||||
# * License as published by the Free Software Foundation; either *
|
||||
# * version 2 of the License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * This library 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 library; see the file COPYING.LIB. If not, *
|
||||
# * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
# * Suite 330, Boston, MA 02111-1307, USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
from Show.SceneDetail import SceneDetail
|
||||
|
||||
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()
|
||||
if not hasattr(v, 'getCamera'):
|
||||
v = gdoc.mdiViewsOfType('Gui::View3DInventor')[0]
|
||||
return v
|
||||
|
||||
def scene_value(self):
|
||||
return self._viewer().getCamera()
|
||||
|
||||
def apply_data(self, val):
|
||||
self._viewer().setCamera(val)
|
||||
|
||||
64
src/Mod/Show/SceneDetails/ClipPlane.py
Normal file
64
src/Mod/Show/SceneDetails/ClipPlane.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This library is free software; you can redistribute it and/or *
|
||||
# * modify it under the terms of the GNU Library General Public *
|
||||
# * License as published by the Free Software Foundation; either *
|
||||
# * version 2 of the License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * This library 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 library; see the file COPYING.LIB. If not, *
|
||||
# * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
# * Suite 330, Boston, MA 02111-1307, USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
from Show.SceneDetail import SceneDetail
|
||||
import FreeCAD as App
|
||||
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
|
||||
(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:
|
||||
if placement is not None and offset != 0.0:
|
||||
placement = placement.copy()
|
||||
dir = placement.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:
|
||||
self._viewer().toggleClippingPlane(enable, pla= pla)
|
||||
else:
|
||||
self._viewer().toggleClippingPlane(enable)
|
||||
|
||||
def _viewer(self):
|
||||
if self.doc is None:
|
||||
gdoc = Gui.editDocument()
|
||||
else:
|
||||
gdoc = Gui.getDocument(self.doc.Name)
|
||||
v = gdoc.activeView()
|
||||
if not hasattr(v, 'toggleClippingPlane'):
|
||||
v = gdoc.mdiViewsOfType('Gui::View3DInventor')[0]
|
||||
return v
|
||||
107
src/Mod/Show/SceneDetails/ObjectClipPlane.py
Normal file
107
src/Mod/Show/SceneDetails/ObjectClipPlane.py
Normal file
@@ -0,0 +1,107 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This library is free software; you can redistribute it and/or *
|
||||
# * modify it under the terms of the GNU Library General Public *
|
||||
# * License as published by the Free Software Foundation; either *
|
||||
# * version 2 of the License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * This library 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 library; see the file COPYING.LIB. If not, *
|
||||
# * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
# * Suite 330, Boston, MA 02111-1307, USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
from Show.SceneDetail import SceneDetail
|
||||
|
||||
import FreeCAD as App
|
||||
|
||||
class ObjectClipPlane(SceneDetail):
|
||||
"""ObjectClipPlane(object, enable = None, placement = None, offset = 0.0):
|
||||
Plugin for TempoVis for adding clipping planes to individual objects."""
|
||||
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
|
||||
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)
|
||||
if cp is None:
|
||||
return self.val(False)
|
||||
else:
|
||||
enable = cp.on.getValue()
|
||||
pln = cp.plane
|
||||
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
|
||||
cp = getClipPlaneNode(vp, make_if_missing= True if enable else False)
|
||||
if cp is None and not enable:
|
||||
return
|
||||
if enable:
|
||||
from pivy import coin
|
||||
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;
|
||||
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)
|
||||
plm_cs = obj.getGlobalPlacement().multiply(obj.Placement.inverse()) # placement of CS the object is in
|
||||
plm_plane = plm_cs.inverse().multiply(placement)
|
||||
pldef = placement2plane(plm_plane, offset)
|
||||
return (enable, pldef if enable else None)
|
||||
|
||||
def getClipPlaneNode(viewprovider, make_if_missing = True):
|
||||
from pivy import coin
|
||||
sa = coin.SoSearchAction()
|
||||
sa.setType(coin.SoClipPlane.getClassTypeId())
|
||||
sa.setName('TVClipPlane')
|
||||
sa.traverse(viewprovider.RootNode)
|
||||
if sa.isFound() and sa.getPath().getLength() == 1:
|
||||
return sa.getPath().getTail()
|
||||
elif not sa.isFound():
|
||||
if not make_if_missing:
|
||||
return None
|
||||
clipplane = coin.SoClipPlane()
|
||||
viewprovider.RootNode.insertChild(clipplane, 0)
|
||||
clipplane.setName('TVClipPlane')
|
||||
clipplane.on.setValue(False) #make sure the plane is not activated by default
|
||||
return clipplane
|
||||
|
||||
def placement2plane(placement, offset):
|
||||
"""returns tuple (normal, D) for making coin plane."""
|
||||
normal = placement.Rotation.multVec(App.Vector(0,0,-1))
|
||||
D = placement.Base * normal - offset
|
||||
return tuple(normal), D
|
||||
|
||||
def clipPlane(obj, enable, placement = None, offset = 0, tv = None):
|
||||
if tv is None:
|
||||
from Show.TempoVis import TempoVis
|
||||
tv = TempoVis(obj.Document)
|
||||
tv.modify(ClipPlane(obj, enable, placement, offset))
|
||||
return tv
|
||||
81
src/Mod/Show/SceneDetails/Pickability.py
Normal file
81
src/Mod/Show/SceneDetails/Pickability.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This library is free software; you can redistribute it and/or *
|
||||
# * modify it under the terms of the GNU Library General Public *
|
||||
# * License as published by the Free Software Foundation; either *
|
||||
# * version 2 of the License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * This library 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 library; see the file COPYING.LIB. If not, *
|
||||
# * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
# * Suite 330, Boston, MA 02111-1307, USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
from Show.SceneDetail import SceneDetail
|
||||
|
||||
class Pickability(SceneDetail):
|
||||
"""Pickability(object, pickstyle = None):Plugin for TempoVis for altering pick style
|
||||
of objects (i.e., selectability).
|
||||
pickstyle may be:
|
||||
PS_REGULAR = 0 # selectable
|
||||
PS_BOUNDBOX = 1 # selectable, but faster hit testing using bounding box
|
||||
PS_UNPICKABLE = 2 # not selectable and not obstructing."""
|
||||
class_id = 'SDPickability'
|
||||
propname = ''
|
||||
objname = ''
|
||||
|
||||
def __init__(self, object, pickstyle = None):
|
||||
self.objname = object.Name
|
||||
self.doc = object.Document
|
||||
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)
|
||||
|
||||
PS_REGULAR = 0
|
||||
PS_BOUNDBOX = 1
|
||||
PS_UNPICKABLE = 2
|
||||
|
||||
def getPickStyleNode(viewprovider, make_if_missing = True):
|
||||
from pivy import coin
|
||||
sa = coin.SoSearchAction()
|
||||
sa.setType(coin.SoPickStyle.getClassTypeId())
|
||||
sa.traverse(viewprovider.RootNode)
|
||||
if sa.isFound() and sa.getPath().getLength() == 1:
|
||||
return sa.getPath().getTail()
|
||||
else:
|
||||
if not make_if_missing:
|
||||
return None
|
||||
pick_style = coin.SoPickStyle()
|
||||
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)
|
||||
if ps is not None:
|
||||
return ps.style.getValue()
|
||||
else:
|
||||
return PS_REGULAR
|
||||
|
||||
def setPickStyle(viewprovider, pickstyle):
|
||||
ps = getPickStyleNode(viewprovider, make_if_missing= pickstyle != 0) #coin.SoPickStyle.SHAPE
|
||||
if ps is not None:
|
||||
return ps.style.setValue(pickstyle)
|
||||
|
||||
48
src/Mod/Show/SceneDetails/VProperty.py
Normal file
48
src/Mod/Show/SceneDetails/VProperty.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This library is free software; you can redistribute it and/or *
|
||||
# * modify it under the terms of the GNU Library General Public *
|
||||
# * License as published by the Free Software Foundation; either *
|
||||
# * version 2 of the License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * This library 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 library; see the file COPYING.LIB. If not, *
|
||||
# * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
# * Suite 330, Boston, MA 02111-1307, USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
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
|
||||
self.doc = object.Document
|
||||
self.key = self.objname + '.' + self.propname
|
||||
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)
|
||||
44
src/Mod/Show/SceneDetails/Workbench.py
Normal file
44
src/Mod/Show/SceneDetails/Workbench.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) Victor Titov (DeepSOIC) *
|
||||
# * (vv.titov@gmail.com) 2019 *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This library is free software; you can redistribute it and/or *
|
||||
# * modify it under the terms of the GNU Library General Public *
|
||||
# * License as published by the Free Software Foundation; either *
|
||||
# * version 2 of the License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * This library 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 library; see the file COPYING.LIB. If not, *
|
||||
# * write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
# * Suite 330, Boston, MA 02111-1307, USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
from Show.SceneDetail import SceneDetail
|
||||
|
||||
import FreeCADGui
|
||||
|
||||
class Workbench(SceneDetail):
|
||||
"""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)
|
||||
|
||||
0
src/Mod/Show/SceneDetails/__init__.py
Normal file
0
src/Mod/Show/SceneDetails/__init__.py
Normal file
Reference in New Issue
Block a user