Draft: get_bbox function to get the bounding box from RootNode

Normally the bounding box is taken from `Shape.BoundBox`.
Certain objects don't have a `Shape`, like `App::FeaturePythons`,
so the bounding box is calculated from `ViewObject.RootNode`.
This commit is contained in:
vocx-fc
2020-09-20 21:40:23 -05:00
committed by Yorik van Havre
parent 312a4652f6
commit 49e1ff1bcf
2 changed files with 73 additions and 2 deletions

View File

@@ -112,7 +112,8 @@ from draftutils.gui_utils import (get3DView,
get_selection_ex,
select,
loadTexture,
load_texture)
load_texture,
get_bbox)
from draftutils.gui_utils import (dim_symbol,
dimSymbol,

View File

@@ -43,7 +43,7 @@ import six
import FreeCAD as App
import draftutils.utils as utils
from draftutils.messages import _msg, _wrn
from draftutils.messages import _msg, _wrn, _err
from draftutils.translate import _tr, translate
if App.GuiUp:
@@ -677,4 +677,74 @@ def migrate_text_display_mode(obj_type="Text", mode="3D text", doc=None):
if utils.get_type(obj) == obj_type:
obj.ViewObject.DisplayMode = mode
def get_bbox(obj, debug=False):
"""Return a BoundBox from any object that has a Coin RootNode.
Normally the bounding box of an object can be taken
from its `Part::TopoShape`.
::
>>> print(obj.Shape.BoundBox)
However, for objects without a `Shape`, such as those
derived from `App::FeaturePython` like `Draft Text` and `Draft Dimension`,
the bounding box can be calculated from the `RootNode` of the viewprovider.
Parameters
----------
obj: App::DocumentObject
Any object that has a `ViewObject.RootNode`.
Returns
-------
Base::BoundBox
It returns a `BoundBox` object which has information like
minimum and maximum values of X, Y, and Z, as well as bounding box
center.
None
If there is a problem it will return `None`.
"""
_name = "get_bbox"
utils.print_header(_name, "Bounding box", debug=debug)
found, doc = utils.find_doc(App.activeDocument())
if not found:
_err(_tr("No active document. Aborting."))
return None
if isinstance(obj, str):
obj_str = obj
found, obj = utils.find_object(obj, doc)
if not found:
_msg("obj: {}".format(obj_str))
_err(_tr("Wrong input: object not in document."))
return None
if debug:
_msg("obj: {}".format(obj.Label))
if (not hasattr(obj, "ViewObject")
or not obj.ViewObject
or not hasattr(obj.ViewObject, "RootNode")):
_err(_tr("Does not have 'ViewObject.RootNode'."))
# For Draft Dimensions
# node = obj.ViewObject.Proxy.node
node = obj.ViewObject.RootNode
view = Gui.ActiveDocument.ActiveView
region = view.getViewer().getSoRenderManager().getViewportRegion()
action = coin.SoGetBoundingBoxAction(region)
node.getBoundingBox(action)
bb = action.getBoundingBox()
# xlength, ylength, zlength = bb.getSize().getValue()
xmin, ymin, zmin = bb.getMin().getValue()
xmax, ymax, zmax = bb.getMax().getValue()
return App.BoundBox(xmin, ymin, zmin, xmax, ymax, zmax)
## @}