Macro BoundingBox Tracing: Difference between revisions

From FreeCAD Documentation
(Vertical {{Macro}}; fixed icon)
(Marked this version for translation)
 
(21 intermediate revisions by 4 users not shown)
Line 5: Line 5:
|Name=Macro BoundingBox Tracing
|Name=Macro BoundingBox Tracing
|Icon=BoundBoxTracing.png
|Icon=BoundBoxTracing.png
|Description=This macro red trace (editable) around the BoundingBox with 6 rectangles.
|Description=Creates a red outline of the BoundingBox (6 Faces with 6 rectangles) of an object, display the dimension of the rectangle, create volume of boundBox.
|Author=Mario52
|Author=Mario52
|Version=0.9
|Version=0.12
|Date=2018-10-12
|Date=2021/07/10
|FCVersion=All
|Download=[https://www.freecadweb.org/wiki/images/6/60/BoundBoxTracing.png ToolBar Icon]
}}
}}


==Description== <!--T:2-->
==Description== <!--T:2-->

This macro red trace (editable) around the BoundingBox 6 Faces with 6 rectangles.
<!--T:31-->
This macro creates a red outline of the BoundingBox (6 Faces with 6 rectangles) of an object, display the dimension of the rectangle, create volume of boundBox.


<!--T:5-->
<!--T:5-->
[[File:Macro BoundingBox_Tracing_00.png|480px]]
:[[File:Macro BoundingBox_Tracing_00.png|480px]]
{{Caption|CenterFace}}
:{{Caption|BoundingBox Tracing macro in action}}

==Usage== <!--T:3-->


==Use== <!--T:3-->
<!--T:24-->
# Select an object
Select the object and launch the macro. 6 rectangles are colored red (can be changed)
# Launch the macro
: Result: 6 rectangles will be outlined in red.


<!--T:15-->
<!--T:15-->
[[File:Macro_BoundingBox_Tracing_01.png|480px]]
:[[File:Macro_BoundingBox_Tracing_01.png|480px]]
{{Caption|Info contener}}
:{{Caption|Info container}}

==Notes== <!--T:25-->


<!--T:6-->
<!--T:6-->
Configuration: see line 61 to 84
If '''createVol''' = 1 (Line 33) one volume is created


==Icon== <!--T:7-->
==Icon== <!--T:7-->

Download the file image and copy in your macro repertory.
<!--T:32-->
Download the file image and copy in to your macro directory.


<!--T:8-->
<!--T:8-->
Click the image, in the new window position the mouse over the image, click the right mouse and do "Save target as ..."
Click the image, in the new window position the mouse over the image, click the right mouse and do "Save target as ..."


<!--T:9-->
<!--T:23-->
[[Image:BoundBoxTracing.png|Button]]
ToolBar Icon [[Image:BoundBoxTracing.png]]


==Script== <!--T:4-->
==Script== <!--T:4-->
Line 42: Line 54:
'''Macro_BoundingBox_Tracing.FCMacro'''
'''Macro_BoundingBox_Tracing.FCMacro'''


{{Code|code=
{{MacroCode|code=
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

# cette macro trace en rouge (modifiable) le tour du boundingbox avec 6 rectangles
# cette macro trace en rouge (modifiable) le tour du boundingbox avec 6 rectangles
# si "createVol" = 1 il sera cree un volume (rouge) de la dimension du BoundBox
# si "createVol" = 1 il sera cree un volume (rouge) de la dimension du BoundBox
Line 61: Line 75:
# #OCC version: 6.8.0.oce-0.17 #Coin version: 4.0.0a #Coin version: 4.0.0a
# #OCC version: 6.8.0.oce-0.17 #Coin version: 4.0.0a #Coin version: 4.0.0a
# #OCC version: 6.8.0.oce-0.17 #OCC version: 7.2.0
# #OCC version: 6.8.0.oce-0.17 #OCC version: 7.2.0
###############################################################################################################################################
#OS: Windows 10 (10.0) #OS: Windows 10 (10.0)
#Word size of OS: 64-bit #Word size of FreeCAD: 64-bit
#Word size of FreeCAD: 64-bit #Version: 0.20.25131 (Git)
#Version: 0.19.16624 (Git) #Build type: Release
#Build type: Release #Branch: master
#Branch: master #Hash: 7c519689f0d5ea78fb3292be36a857d283c05507
#Hash: 222ae7305fdf1097e4ef3d050f69dff47dbd8786 #Python version: 3.8.10
#Python version: 3.6.8 #Qt version: 5.12.9
#Qt version: 5.12.1 #Coin version: 4.0.0
#Coin version: 4.0.0a #OCC version: 7.5.2
#OCC version: 7.3.0 #Locale: French/Mars (fr_MA)
###############################################################################################################################################
#
#2021/07/10 modified by edwilliams16 to handle objects in nested part containers
#https://forum.freecadweb.org/viewtopic.php?f=22&t=59852
#
#

__title__ = "BoundingBox_Tracing"
__title__ = "BoundingBox_Tracing"
__author__ = "Mario52"
__author__ = "Mario52"
__url__ = "http://www.freecadweb.org/index-fr.html"
__url__ = "http://www.freecadweb.org/index-fr.html"
__Wiki__ = "https://www.freecadweb.org/wiki/Macro_BoundingBox_Tracing"
__Wiki__ = "https://www.freecadweb.org/wiki/Macro_BoundingBox_Tracing"
__version__ = "0.9"
__version__ = "0.12"
__date__ = "12/10/2018" #
__date__ = "2021/07/10" # YYYY/MM/DD




import PySide
import FreeCAD, FreeCADGui, Draft, Part
import FreeCAD, FreeCADGui, Draft, Part
App = FreeCAD
App = FreeCAD
import sys

debug = False
if debug:
from sys import path
sys.path.append('/Users/ed/opt/anaconda3/lib/python3.7/site-packages')
import ptvsd
print("Waiting for debugger attach")
# 5678 is the default attach port in the VS Code debug configurations
ptvsd.enable_attach(address=('localhost', 5678), redirect_output=True)
ptvsd.wait_for_attach()


##### Section configuration begin ##################
##### Section configuration begin ##################
Line 84: Line 125:


if int(FreeCAD.Version()[1]) > 17: # Version de FreeCAD
if int(FreeCAD.Version()[1]) > 17: # Version de FreeCAD
DisplayModeText = str(u"2D text") # available : u"2D text" or u"3D text"
DisplayModeText = str(u"3D text") # available : u"2D text" or u"3D text"
else:
else:
DisplayModeText = str(u"Screen") # available : u"Screen" or u"World"
DisplayModeText = str(u"Screen") # available : u"Screen" or u"World"


JustificationText = "Center" # available : "Center" or "Left" or "Right"
JustificationText = str(u"Center") # available : "Center" or "Left" or "Right"
FontSizeText = 10.0 # text info dimension
FontSizeText = 3.0 # text info dimension
TextColorText_R = 0.0 # text color info red 1 = 255
TextColorText_R = 0.0 # text color info red 1 = 255
TextColorText_G = 0.0 # text color info green 1 = 255
TextColorText_G = 0.0 # text color info green 1 = 255
Line 98: Line 139:
##### Section configuration end ####################
##### Section configuration end ####################



def objectRealPlacement3D(obj, mode = 0): # search the real Placement
def adjustedGlobalPlacement(obj, locVector):
'''find global placement to make locVector the local origin with the correct orientation'''
try:
try:
objectPlacement = obj.Shape.Placement
objectPlacement = obj.Shape.Placement
objectGlobalPlacement = obj.getGlobalPlacement()
objectPlacementBase = FreeCAD.Vector(objectPlacement.Base)
locPlacement = App.Placement(locVector, App.Rotation(App.Vector(1,0,0),0))

return objectGlobalPlacement.multiply(objectPlacement.inverse()).multiply(locPlacement)
####
if mode == 0: # Base
objectWorkCenter = objectPlacementBase
elif mode == 1: # BoundBox
objectBoundBoxCenter = FreeCAD.Vector(obj.Shape.BoundBox.Center)
objectWorkCenter = objectBoundBoxCenter
elif mode == 2: # CenterOfMass
objectCenterOfMass = FreeCAD.Vector(obj.Shape.CenterOfMass)
objectWorkCenter = objectCenterOfMass
####
if hasattr(obj, "getGlobalPlacement"):
globalPlacement = obj.getGlobalPlacement()
globalPlacementBase = FreeCAD.Vector(globalPlacement.Base)
# objectRealPlacement3D = globalPlacementBase.add(objectWorkCenter).sub(objectPlacementBase)#ori
objectRealPlacement3D = globalPlacementBase.sub(objectWorkCenter)# adapte pour BB
else:
objectRealPlacement3D = objectWorkCenter

return objectRealPlacement3D
except Exception:
except Exception:
return FreeCAD.Vector(0.0, 0.0, 0.0)
locPlacement = App.Placement(App.Vector(0,0,0), App.Rotation(0,0,0), App.Vector(0,0,0))
return locPlacement




Line 146: Line 171:
# boundBox
# boundBox
boundBox_ = s.BoundBox
boundBox_ = s.BoundBox
boundBoxLX = boundBox_.XLength
boundBoxLX = boundBox_.XLength
boundBoxLY = boundBox_.YLength
boundBoxLY = boundBox_.YLength
boundBoxLZ = boundBox_.ZLength
boundBoxLZ = boundBox_.ZLength
boundBoxXMin = boundBox_.XMin
boundBoxYMin = boundBox_.YMin
boundBoxZMin = boundBox_.ZMin
boundBoxLocation = App.Vector(boundBox_.XMin,boundBox_.YMin,boundBox_.ZMin)
nameLabel = sel[0].Label
nameLabel = sel[0].Label

import unicodedata
nameLabel = unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore')
a = str(boundBox_)
a,b = a.split('(')
c = b.split(',')
oripl_X = float(c[0])
oripl_Y = float(c[1])
oripl_Z = float(c[2])
try:
try:
import unicodedata
if objs[0].getParentGeoFeatureGroup() == None:
placementOrigine = FreeCAD.Vector(0.0, 0.0, 0.0)
nameLabel = str(unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore'))[2:]
else:
placementOrigine = objectRealPlacement3D(FreeCAD.ActiveDocument.getObject(objs[0].Name),0)# search the real Placement
oripl_X += placementOrigine[0]
oripl_Y += placementOrigine[1]
oripl_Z += placementOrigine[2]
except Exception:
except Exception:
None
None

App.Console.PrintMessage(str(boundBox_)+"\r\n")
App.Console.PrintMessage(str(boundBox_)+"\r\n")
App.Console.PrintMessage("Rectangle : "+str(boundBoxLX)+" x "+str(boundBoxLY)+" x "+str(boundBoxLZ)+"\r\n")
App.Console.PrintMessage("Rectangle : "+str(boundBoxLX)+" x "+str(boundBoxLY)+" x "+str(boundBoxLZ)+"\r\n")

if (createVol == 1) and (boundBoxLX > 0) and (boundBoxLY > 0) and (boundBoxLZ > 0): # Create Volume
if (createVol == 1) and (boundBoxLX > 0) and (boundBoxLY > 0) and (boundBoxLZ > 0): # Create Volume
BDvol = App.ActiveDocument.addObject("Part::Box",nameLabel + "_BoundBoxVolume")
BDvol = App.ActiveDocument.addObject("Part::Box",nameLabel + "_BoundBoxVolume")
Line 182: Line 196:
BDvol.Width.Value = boundBoxLY
BDvol.Width.Value = boundBoxLY
BDvol.Height.Value = boundBoxLZ
BDvol.Height.Value = boundBoxLZ
BDvol.Placement=App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(App.Vector(0,0,1),0), App.Vector(0,0,0))
BDvol.Placement = adjustedGlobalPlacement(objs[0], boundBoxLocation)
BDPl = BDvol.Placement
oripl_X=BDvol.Placement.Base.x
oripl_Y=BDvol.Placement.Base.y
oripl_Z=BDvol.Placement.Base.z
#if debug: print(f'global {globalObjectPlacement}\n local {localObjectPlacement} BB {BBlocPlacement}')
FreeCADGui.ActiveDocument.getObject(BDvol.Name).LineColor = (red, green, blue)
FreeCADGui.ActiveDocument.getObject(BDvol.Name).LineColor = (red, green, blue)
FreeCADGui.ActiveDocument.getObject(BDvol.Name).PointColor = (red, green, blue)
FreeCADGui.ActiveDocument.getObject(BDvol.Name).PointColor = (red, green, blue)
Line 194: Line 213:
conteneurVol = App.activeDocument().addObject("App::DocumentObjectGroup",nameLabel + "_BoundBoxVolume_Info")
conteneurVol = App.activeDocument().addObject("App::DocumentObjectGroup",nameLabel + "_BoundBoxVolume_Info")
pl_0C1 = Draft.makeText([str(round(boundBoxLX,arondi))],point=FreeCAD.Vector(oripl_X + (boundBoxLX/2), oripl_Y, oripl_Z))
#pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],point=FreeCAD.Vector(oripl_X + (boundBoxLX/2), oripl_Y, oripl_Z))
pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement = BDPl.multVec(App.Vector(boundBoxLX/2,0,0)))
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.Justification = JustificationText
Line 202: Line 222:
conteneurVol.addObject(pl_0C1)
conteneurVol.addObject(pl_0C1)
pl_0C2 = Draft.makeText([str(round(boundBoxLY,arondi))],point=FreeCAD.Vector(oripl_X, oripl_Y + (boundBoxLY/2), oripl_Z))
#pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],point=FreeCAD.Vector(oripl_X, oripl_Y + (boundBoxLY/2), oripl_Z))
pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement = BDPl.multVec(App.Vector(0, boundBoxLY/2, 0)))
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.Justification = JustificationText
pl_0C2.ViewObject.Justification = JustificationText
Line 210: Line 231:
conteneurVol.addObject(pl_0C2)
conteneurVol.addObject(pl_0C2)
pl_0C3 = Draft.makeText([str(round(boundBoxLZ,arondi))],point=FreeCAD.Vector(oripl_X, oripl_Y, oripl_Z + (boundBoxLZ/2)))
#pl_0C3 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=FreeCAD.Vector(oripl_X, oripl_Y, oripl_Z + (boundBoxLZ/2)))
pl_0C3 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement = BDPl.multVec(App.Vector(0, 0, boundBoxLZ/2)))
pl_0C3.ViewObject.DisplayMode = DisplayModeText
pl_0C3.ViewObject.DisplayMode = DisplayModeText
pl_0C3.ViewObject.Justification = JustificationText
pl_0C3.ViewObject.Justification = JustificationText
Line 220: Line 242:
# else:
# else:
# App.Console.PrintMessage("Not Volume BoundBox possible"+"\r\n")
# App.Console.PrintMessage("Not Volume BoundBox possible"+"\r\n")
# App.Console.PrintMessage("_____________________"+"\r\n")
App.Console.PrintMessage("_____________________"+"\r\n")

App.Console.PrintMessage("_____________________"+"\n\n")
#####
#####
Line 234: Line 256:
try:
try:
if (boundBoxLX and boundBoxLY) > 0.0:
if (boundBoxLX and boundBoxLY) > 0.0:
pl_0 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,0.0))
#pl_0 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,0.0))
pl_0 = adjustedGlobalPlacement(objs[0], boundBoxLocation)
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLY,placement=pl_0,face=False,support=None) #OK
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLY,placement=pl_0,face=False,support=None) #OK
double.Label = nameLabel + "_BoundBoxRectangle_Bo"
double.Label = nameLabel + "_BoundBoxRectangle_Bo"
Line 243: Line 266:
if createDim == 1: # section create dimension info
if createDim == 1: # section create dimension info
pl_0C1 = Draft.makeText([str(round(boundBoxLX,arondi))],point=FreeCAD.Vector(pl_0.Base.x + (boundBoxLX/2), pl_0.Base.y, pl_0.Base.z))
#pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=FreeCAD.Vector(pl_0.Base.x + (boundBoxLX/2), pl_0.Base.y, pl_0.Base.z))
# XY -> XY
pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_0.multVec(App.Vector(boundBoxLX/2, 0, 0)))
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.Justification = JustificationText
Line 251: Line 276:
conteneurInfo.addObject(pl_0C1)
conteneurInfo.addObject(pl_0C1)
pl_0C2 = Draft.makeText([str(round(boundBoxLY,arondi))],point=FreeCAD.Vector(pl_0.Base.x, pl_0.Base.y + (boundBoxLY/2), pl_0.Base.z))
#pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=FreeCAD.Vector(pl_0.Base.x, pl_0.Base.y + (boundBoxLY/2), pl_0.Base.z))
pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_0.multVec(App.Vector(0., boundBoxLY/2, 0.)))
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.Justification = JustificationText
pl_0C2.ViewObject.Justification = JustificationText
Line 264: Line 290:
try:
try:
if (boundBoxLX and boundBoxLY) > 0.0:
if (boundBoxLX and boundBoxLY) > 0.0:
pl_1 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z+boundBoxLZ), App.Rotation(0.0,0.0,0.0))
#pl_1 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z+boundBoxLZ), App.Rotation(0.0,0.0,0.0))
pl_1 =adjustedGlobalPlacement(objs[0], boundBoxLocation + App.Vector(0,0,boundBoxLZ))
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLY,placement=pl_1,face=False,support=None) #Ok
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLY,placement=pl_1,face=False,support=None) #Ok
double.Label = nameLabel + "_BoundBoxRectangle_To"
double.Label = nameLabel + "_BoundBoxRectangle_To"
Line 273: Line 300:
if createDim == 1: # section create dimension info
if createDim == 1: # section create dimension info
pl_0C1 = Draft.makeText([str(round(boundBoxLX,arondi))],point=FreeCAD.Vector(pl_1.Base.x + (boundBoxLX/2), pl_1.Base.y, pl_1.Base.z))
#pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=FreeCAD.Vector(pl_1.Base.x + (boundBoxLX/2), pl_1.Base.y, pl_1.Base.z))
#XY -> XY
pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_1.multVec(App.Vector(boundBoxLX/2, 0, 0)))
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.Justification = JustificationText
Line 281: Line 310:
conteneurInfo.addObject(pl_0C1)
conteneurInfo.addObject(pl_0C1)
pl_0C2 = Draft.makeText([str(round(boundBoxLY,arondi))],point=FreeCAD.Vector(pl_1.Base.x, pl_1.Base.y + (boundBoxLY/2), pl_1.Base.z))
#pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=FreeCAD.Vector(pl_1.Base.x, pl_1.Base.y + (boundBoxLY/2), pl_1.Base.z))
pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_1.multVec(App.Vector(0., boundBoxLY/2, 0)))

pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.Justification = JustificationText
pl_0C2.ViewObject.Justification = JustificationText
Line 294: Line 325:
try:
try:
if (boundBoxLX and boundBoxLZ) > 0.0:
if (boundBoxLX and boundBoxLZ) > 0.0:
pl_2 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,90))
#pl_2 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,90))
pl_2 = pl_0.multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(0.0,0.0,90)))
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLZ,placement=pl_2,face=False,support=None) #Ok
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLZ,placement=pl_2,face=False,support=None) #Ok
double.Label = nameLabel + "_BoundBoxRectangle_Fr"
double.Label = nameLabel + "_BoundBoxRectangle_Fr"
Line 303: Line 335:
if createDim == 1: # section create dimension info
if createDim == 1: # section create dimension info
pl_0C1 = Draft.makeText([str(round(boundBoxLX,arondi))],point=FreeCAD.Vector(pl_2.Base.x + (boundBoxLX/2), pl_2.Base.y, pl_2.Base.z))
#pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=FreeCAD.Vector(pl_2.Base.x + (boundBoxLX/2), pl_2.Base.y, pl_2.Base.z))
#XZ -> XY
pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_2.multVec(App.Vector(boundBoxLX/2, 0, 0)))
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.Justification = JustificationText
Line 311: Line 345:
conteneurInfo.addObject(pl_0C1)
conteneurInfo.addObject(pl_0C1)
pl_0C2 = Draft.makeText([str(round(boundBoxLZ,arondi))],point=FreeCAD.Vector(pl_2.Base.x, pl_2.Base.y, pl_2.Base.z + (boundBoxLZ/2)))
#pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=FreeCAD.Vector(pl_2.Base.x, pl_2.Base.y, pl_2.Base.z + (boundBoxLZ/2)))
pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_2.multVec(App.Vector(0, boundBoxLZ/2, 0)))
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.Justification = JustificationText
pl_0C2.ViewObject.Justification = JustificationText
Line 324: Line 359:
try:
try:
if (boundBoxLX and boundBoxLZ) > 0.0:
if (boundBoxLX and boundBoxLZ) > 0.0:
pl_3 = App.Placement(App.Vector(oripl_X,oripl_Y+boundBoxLY,oripl_Z), App.Rotation(0.0,0.0,90))
#pl_3 = App.Placement(App.Vector(oripl_X,oripl_Y+boundBoxLY,oripl_Z), App.Rotation(0.0,0.0,90))
pl_3 = adjustedGlobalPlacement(objs[0], boundBoxLocation+App.Vector(0, boundBoxLY, 0)).multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(0.0,0.0,90)))
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLZ,placement=pl_3,face=False,support=None) #Ok
double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLZ,placement=pl_3,face=False,support=None) #Ok
double.Label = nameLabel + "_BoundBoxRectangle_Re"
double.Label = nameLabel + "_BoundBoxRectangle_Re"
Line 333: Line 369:
if createDim == 1: # section create dimension info
if createDim == 1: # section create dimension info
#XZ -> XY
pl_0C1 = Draft.makeText([str(round(boundBoxLX,arondi))],point=FreeCAD.Vector(pl_3.Base.x + (boundBoxLX/2), pl_3.Base.y, pl_3.Base.z))
pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_3.multVec(App.Vector(boundBoxLX/2, 0, 0)))
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.Justification = JustificationText
Line 341: Line 378:
conteneurInfo.addObject(pl_0C1)
conteneurInfo.addObject(pl_0C1)
pl_0C2 = Draft.makeText([str(round(boundBoxLZ,arondi))],point=FreeCAD.Vector(pl_3.Base.x, pl_3.Base.y, pl_3.Base.z + (boundBoxLZ/2)))
pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_3.multVec(App.Vector(0, boundBoxLZ/2, 0)))
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.Justification = JustificationText
pl_0C2.ViewObject.Justification = JustificationText
Line 354: Line 391:
try:
try:
if (boundBoxLY and boundBoxLZ) > 0.0:
if (boundBoxLY and boundBoxLZ) > 0.0:
pl_4 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
#pl_4 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
pl_4 = pl_0.multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(90,0,90)))
double = Draft.makeRectangle(length=boundBoxLY,height=boundBoxLZ,placement=pl_4,face=False,support=None) #Ok
double = Draft.makeRectangle(length=boundBoxLY,height=boundBoxLZ,placement=pl_4,face=False,support=None) #Ok
double.Label = nameLabel + "_BoundBoxRectangle_Le"
double.Label = nameLabel + "_BoundBoxRectangle_Le"
Line 363: Line 401:
if createDim == 1: # section create dimension info
if createDim == 1: # section create dimension info
pl_0C1 = Draft.makeText([str(round(boundBoxLY,arondi))],point=FreeCAD.Vector(pl_4.Base.x, pl_4.Base.y + (boundBoxLY/2), pl_4.Base.z))
#pl_0C1 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=FreeCAD.Vector(pl_4.Base.x, pl_4.Base.y + (boundBoxLY/2), pl_4.Base.z))
#YZ ->XY
pl_0C1 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_4.multVec(App.Vector(boundBoxLY/2, 0., 0.)))
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.Justification = JustificationText
Line 371: Line 411:
conteneurInfo.addObject(pl_0C1)
conteneurInfo.addObject(pl_0C1)
pl_0C2 = Draft.makeText([str(round(boundBoxLZ,arondi))],point=FreeCAD.Vector(pl_4.Base.x, pl_4.Base.y, pl_4.Base.z + (boundBoxLZ/2)))
#pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=FreeCAD.Vector(pl_4.Base.x, pl_4.Base.y, pl_4.Base.z + (boundBoxLZ/2)))
pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_4.multVec(App.Vector(0., boundBoxLZ/2, 0)))
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.Justification = JustificationText
pl_0C2.ViewObject.Justification = JustificationText
Line 384: Line 425:
try:
try:
if (boundBoxLY and boundBoxLZ) > 0.0:
if (boundBoxLY and boundBoxLZ) > 0.0:
pl_5 = App.Placement(App.Vector(oripl_X+boundBoxLX,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
#pl_5 = App.Placement(App.Vector(oripl_X+boundBoxLX,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
pl_5 = adjustedGlobalPlacement(objs[0], boundBoxLocation+App.Vector(boundBoxLX,0,0)).multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(90,0.0,90)))
double = Draft.makeRectangle(length=boundBoxLY,height=boundBoxLZ,placement=pl_5,face=False,support=None) #Ok
double = Draft.makeRectangle(length=boundBoxLY,height=boundBoxLZ,placement=pl_5,face=False,support=None) #Ok
double.Label = nameLabel + "_BoundBoxRectangle_Ri"
double.Label = nameLabel + "_BoundBoxRectangle_Ri"
Line 393: Line 435:
if createDim == 1: # section create dimension info
if createDim == 1: # section create dimension info
#YZ-> XY
pl_0C1 = Draft.makeText([str(round(boundBoxLY,arondi))],point=FreeCAD.Vector(pl_5.Base.x, pl_5.Base.y + (boundBoxLY/2), pl_5.Base.z))
pl_0C1 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_5.multVec(App.Vector(boundBoxLY/2, 0, 0)))
pl_0C1.ViewObject.DisplayMode = DisplayModeText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.Justification = JustificationText
pl_0C1.ViewObject.TextColor = (TextColorText_R, TextColorText_G, TextColorText_B)
pl_0C1.ViewObject.TextColor = (TextColorText_R, TextColorText_G, TextColorText_B)
Line 401: Line 443:
conteneurInfo.addObject(pl_0C1)
conteneurInfo.addObject(pl_0C1)
pl_0C2 = Draft.makeText([str(round(boundBoxLZ,arondi))],point=FreeCAD.Vector(pl_5.Base.x, pl_5.Base.y, pl_5.Base.z + (boundBoxLZ/2)))
pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_5.multVec(App.Vector(0, boundBoxLZ/2, 0 )))
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.DisplayMode = DisplayModeText
pl_0C2.ViewObject.Justification = JustificationText
pl_0C2.ViewObject.Justification = JustificationText
Line 418: Line 460:
else:
else:
App.Console.PrintMessage("Select an object !"+"\n")
App.Console.PrintMessage("Select an object !"+"\n")



}}
}}


<translate>
<translate>
===Options=== <!--T:18-->
To change the color or other options change the values lines 31 to 49 Section configuration
</translate>


==Version== <!--T:12-->
{{ExampleCode|example=
##### Section configuration begin ##################
##### for volume begin ###################
createVol = 1 # give 1 for create Volume # mettre a 1 pour creer un volume
createDimVol = 1 # 1 = create dimension info : 0 = not dimension info


<!--T:26-->
##### for volume end ###################
Version: 0.12 Date 2021/07/10: upgrade by edwilliams16 to handle objects in nested part containers. [https://forum.freecadweb.org/viewtopic.php?f=22&t=59852 FCInfo CG of assemblies] corrected the global placement, thanks edwilliams16


</translate>
##### for dimensions info begin ##########
{{Code|code=
createDim = 1 # 1 = create dimension info : 0 = not create dimension info
DisplayModeText = "Screen" # available : "Screen" or "World"
JustificationText = "Center" # available : "Center" or "Left" or "Right"
FontSizeText = 10.0 # text info dimension
TextColorText_R = 0.0 # text color info red 1 = 255
TextColorText_G = 0.0 # text color info green 1 = 255
TextColorText_B = 0.0 # text color info blue 1 = 255
arondi = 3 # round the info ex: 3 = 3 decimals


def adjustedGlobalPlacement(obj, locVector):
##### for dimensions info end ##########
'''find global placement to make locVector the local origin with the correct orientation'''
##### Section configuration end ####################
try:
objectPlacement = obj.Shape.Placement
objectGlobalPlacement = obj.getGlobalPlacement()
locPlacement = App.Placement(locVector, App.Rotation(App.Vector(1,0,0),0))
return objectGlobalPlacement.multiply(objectPlacement.inverse()).multiply(locPlacement)
except Exception:
locPlacement = App.Placement(App.Vector(0,0,0), App.Rotation(0,0,0), App.Vector(0,0,0))
return locPlacement


}}
}}

<translate>
<translate>

==Version== <!--T:12-->
<!--T:30-->
Version: 0.11 Date: 2019/05/29: "nameLabel = str(unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore'))" instead "def()"

<!--T:22-->
Version: 0.10 Date: 2019/05/23 upgrade > 0.19 and supp the "éçà.." with def() not encode()....


<!--T:21-->
<!--T:21-->
ver 0.9 le 2018-10-12: add test > 17
Version: 0.9 le 2018-10-12: add test > 17
</translate>
</translate>
{{Code|code=
{{Code|code=
Line 467: Line 504:


<!--T:19-->
<!--T:19-->
ver 0.8 le 05/10/2018: upgrade the ver 0.8 compatible with FC 0.17 (getGlobalPlacement)
Version: 0.8 Date: 05/10/2018: upgrade the ver 0.8 compatible with FC 0.17 (getGlobalPlacement)


<!--T:17-->
<!--T:17-->
ver 0.7 le 28/01/2018: correct error with label accent "nameLabel = unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore')"
Version: 0.7 Date: 28/01/2018: correct error with label accent "nameLabel = unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore')"


<!--T:14-->
<!--T:14-->
ver 0.6 le 08/08/2017: add text info dimension , contener for rectangles, info rectangles, info volume, add section configuration color , label object selected
Version: 0.6 Date: 08/08/2017: add text info dimension , contener for rectangles, info rectangles, info volume, add section configuration color , label object selected


<!--T:16-->
<!--T:16-->
ver 0.5 le 08/05/2017 : upgrade now accept the "mesh" and "Points" thanks wmayer [http://forum.freecadweb.org/viewtopic.php?f=13&t=22331 Makro Bounding-Box für STL importierte Teile und für Punktewolken]
Version: 0.5 Date: 08/05/2017 : upgrade now accept the "mesh" and "Points" thanks wmayer [http://forum.freecadweb.org/viewtopic.php?f=13&t=22331 Makro Bounding-Box für STL importierte Teile und für Punktewolken]


<!--T:13-->
<!--T:13-->
ver 0.4 le 04/06/2016 : test if value = 0 then not create boundbox (ex: object Draft)
Version: 0.4 Date: 04/06/2016 : test if value = 0 then not create boundbox (ex: object Draft)

</translate>
</translate>

Latest revision as of 10:28, 18 June 2023

Macro BoundingBox Tracing

Description
Creates a red outline of the BoundingBox (6 Faces with 6 rectangles) of an object, display the dimension of the rectangle, create volume of boundBox.

Macro version: 0.12
Last modified: 2021/07/10
FreeCAD version: All
Download: ToolBar Icon
Author: Mario52
Author
Mario52
Download
ToolBar Icon
Links
Macro Version
0.12
Date last modified
2021/07/10
FreeCAD Version(s)
All
Default shortcut
None
See also
None

Description

This macro creates a red outline of the BoundingBox (6 Faces with 6 rectangles) of an object, display the dimension of the rectangle, create volume of boundBox.

BoundingBox Tracing macro in action

Usage

  1. Select an object
  2. Launch the macro
Result: 6 rectangles will be outlined in red.

Info container

Notes

Configuration: see line 61 to 84

Icon

Download the file image and copy in to your macro directory.

Click the image, in the new window position the mouse over the image, click the right mouse and do "Save target as ..."

ToolBar Icon

Script

Macro_BoundingBox_Tracing.FCMacro

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

# cette macro trace en rouge (modifiable) le tour du boundingbox avec 6 rectangles
# si "createVol" = 1 il sera cree un volume (rouge) de la dimension du BoundBox
# this macro red trace (editable) around the BoundingBox with 6 rectangles
# if "createVol" = 1 on volume (red) is created 
# Macro_BoundingBox_Tracing
#
#OS: Windows Vista     #OS: Windows 8.1                                #OS: Windows 10                                 #OS: Windows 10
#Platform: 32-bit      #Word size of OS: 64-bit                        #Word size of OS: 64-bit                        #Word size of OS: 64-bit
#Version: 0.14.3389    #Word size of FreeCAD: 64-bit                   #Word size of FreeCAD: 64-bit                   #Word size of FreeCAD: 64-bit
#Python version: 2.6.2 #Version: 0.15.4671 (Git)                       #Version: 0.16.6700 (Git)                       #Version: 0.17.13528 (Git)
#Qt version: 4.5.2     #Branch: releases/FreeCAD-0-15                  #Build type: Release                            #Build type: Release
#Coin version: 3.1.0   #Hash: 244b3aef360841646cbfe80a1b225c8b39c8380c #Branch: releases/FreeCAD-0-16                  #Branch: releases/FreeCAD-0-17
#SoQt version: 1.4.1   #Python version: 2.7.8                          #Hash: 7b925d11aa69ac405b423635adb1e2833f18a817 #Hash: 5c3f7bf8ec51e2c7187789f7edba71a7aa82a88b
#OCC version: 6.5.1    #Qt version: 4.8.6                              #Python version: 2.7.8                          #Python version: 2.7.14
#                      #Coin version: 4.0.0a                           #Qt version: 4.8.6                              #Qt version: 4.8.7
#                      #OCC version: 6.8.0.oce-0.17                    #Coin version: 4.0.0a                           #Coin version: 4.0.0a
#                                                                      #OCC version: 6.8.0.oce-0.17                    #OCC version: 7.2.0
###############################################################################################################################################
#OS: Windows 10 (10.0)                                #OS: Windows 10 (10.0)
#Word size of OS: 64-bit                              #Word size of FreeCAD: 64-bit
#Word size of FreeCAD: 64-bit                         #Version: 0.20.25131 (Git)
#Version: 0.19.16624 (Git)                            #Build type: Release
#Build type: Release                                  #Branch: master
#Branch: master                                       #Hash: 7c519689f0d5ea78fb3292be36a857d283c05507
#Hash: 222ae7305fdf1097e4ef3d050f69dff47dbd8786       #Python version: 3.8.10
#Python version: 3.6.8                                #Qt version: 5.12.9
#Qt version: 5.12.1                                   #Coin version: 4.0.0
#Coin version: 4.0.0a                                 #OCC version: 7.5.2
#OCC version: 7.3.0                                   #Locale: French/Mars (fr_MA)
###############################################################################################################################################
#
#2021/07/10 modified by edwilliams16 to handle objects in nested part containers
#https://forum.freecadweb.org/viewtopic.php?f=22&t=59852
#
__title__   = "BoundingBox_Tracing"
__author__  = "Mario52"
__url__     = "http://www.freecadweb.org/index-fr.html"
__Wiki__    = "https://www.freecadweb.org/wiki/Macro_BoundingBox_Tracing"
__version__ = "0.12"
__date__    = "2021/07/10" #  YYYY/MM/DD


import PySide
import FreeCAD, FreeCADGui, Draft, Part
App = FreeCAD
import sys

debug = False
if debug:
    from sys import path
    sys.path.append('/Users/ed/opt/anaconda3/lib/python3.7/site-packages')
    import ptvsd
    print("Waiting for debugger attach")
    # 5678 is the default attach port in the VS Code debug configurations
    ptvsd.enable_attach(address=('localhost', 5678), redirect_output=True)
    ptvsd.wait_for_attach()

##### Section configuration begin ##################
##### for volume begin ###################
createVol         = 1           # give 1 for create Volume # mettre a 1 pour creer un volume
createDimVol      = 1           # 1 = create dimension info : 0 = not dimension info
##### for volume end   ###################

##### for dimensions info begin ##########
createDim         = 1           # 1 = create dimension info : 0 = not create dimension info

if int(FreeCAD.Version()[1]) > 17:      # Version de FreeCAD
    DisplayModeText   = str(u"3D text") # available : u"2D text" or u"3D text" 
else:
    DisplayModeText   = str(u"Screen")  # available : u"Screen" or u"World" 

JustificationText = str(u"Center")    # available : "Center" or "Left" or "Right"
FontSizeText      = 3.0         # text info dimension
TextColorText_R   = 0.0         # text color info red      1 = 255
TextColorText_G   = 0.0         # text color info green    1 = 255
TextColorText_B   = 0.0         # text color info blue     1 = 255
arondi            = 3           # round the info ex: 3 = 3 decimals

##### for dimensions info end   ##########
##### Section configuration end ####################


def adjustedGlobalPlacement(obj, locVector):
    '''find global placement to make locVector the local origin with the correct orientation'''
    try:
        objectPlacement = obj.Shape.Placement
        objectGlobalPlacement = obj.getGlobalPlacement()
        locPlacement = App.Placement(locVector, App.Rotation(App.Vector(1,0,0),0))
        return objectGlobalPlacement.multiply(objectPlacement.inverse()).multiply(locPlacement)
    except Exception:
        locPlacement = App.Placement(App.Vector(0,0,0), App.Rotation(0,0,0), App.Vector(0,0,0))
        return locPlacement


sel   = FreeCADGui.Selection.getSelection()
selEx = FreeCADGui.Selection.getSelectionEx()
objs  = [selobj.Object for selobj in selEx]
    
if len(objs) >= 1:
    if hasattr(objs[0], "Shape"):
        s = objs[0].Shape
    elif hasattr(objs[0], "Mesh"):      # upgrade with wmayer thanks #http://forum.freecadweb.org/viewtopic.php?f=13&t=22331
        s = objs[0].Mesh
    elif hasattr(objs[0], "Points"):
        s = objs[0].Points

    try:
        # LineColor
        red   = 1.0  # 1 = 255
        green = 0.0  #
        blue  = 0.0  #
    
        # boundBox
        boundBox_    = s.BoundBox
        boundBoxLX   = boundBox_.XLength
        boundBoxLY   = boundBox_.YLength
        boundBoxLZ   = boundBox_.ZLength
        boundBoxXMin = boundBox_.XMin
        boundBoxYMin = boundBox_.YMin
        boundBoxZMin = boundBox_.ZMin
        boundBoxLocation = App.Vector(boundBox_.XMin,boundBox_.YMin,boundBox_.ZMin)
        nameLabel  = sel[0].Label

        try:
            import unicodedata    
            nameLabel = str(unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore'))[2:]
        except Exception:
            None

        App.Console.PrintMessage(str(boundBox_)+"\r\n")
        App.Console.PrintMessage("Rectangle      : "+str(boundBoxLX)+" x "+str(boundBoxLY)+" x "+str(boundBoxLZ)+"\r\n")
        
        if (createVol == 1) and (boundBoxLX > 0) and (boundBoxLY > 0) and (boundBoxLZ > 0):  # Create Volume
            BDvol = App.ActiveDocument.addObject("Part::Box",nameLabel + "_BoundBoxVolume")
            #BDvol.Label = "BoundBoxVolume"
            BDvol.Length.Value = boundBoxLX
            BDvol.Width.Value  = boundBoxLY
            BDvol.Height.Value = boundBoxLZ
            BDvol.Placement = adjustedGlobalPlacement(objs[0], boundBoxLocation)
            BDPl = BDvol.Placement
            oripl_X=BDvol.Placement.Base.x
            oripl_Y=BDvol.Placement.Base.y
            oripl_Z=BDvol.Placement.Base.z
            #if debug: print(f'global {globalObjectPlacement}\n local {localObjectPlacement} BB {BBlocPlacement}')
            FreeCADGui.ActiveDocument.getObject(BDvol.Name).LineColor  = (red, green, blue)
            FreeCADGui.ActiveDocument.getObject(BDvol.Name).PointColor = (red, green, blue)
            FreeCADGui.ActiveDocument.getObject(BDvol.Name).ShapeColor = (red, green, blue)
            FreeCADGui.ActiveDocument.getObject(BDvol.Name).Transparency = 80
            App.Console.PrintMessage(nameLabel + "_BoundBoxVolume : " + str(BDvol.Shape.Volume)+"\r\n")
    
            if createDimVol == 1:    # section create dimension info for volume
                conteneurVol = []
                del conteneurVol[:]
                conteneurVol = App.activeDocument().addObject("App::DocumentObjectGroup",nameLabel + "_BoundBoxVolume_Info")
    
                #pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],point=FreeCAD.Vector(oripl_X + (boundBoxLX/2), oripl_Y, oripl_Z))
                pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement = BDPl.multVec(App.Vector(boundBoxLX/2,0,0)))
                pl_0C1.ViewObject.DisplayMode   = DisplayModeText
                pl_0C1.ViewObject.Justification = JustificationText
                pl_0C1.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C1.ViewObject.FontSize      = FontSizeText
                pl_0C1.Label      = nameLabel + "_Volume_X_" + str(round(boundBoxLX,arondi))
                conteneurVol.addObject(pl_0C1)
    
                #pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],point=FreeCAD.Vector(oripl_X, oripl_Y + (boundBoxLY/2), oripl_Z))
                pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement = BDPl.multVec(App.Vector(0, boundBoxLY/2, 0)))
                pl_0C2.ViewObject.DisplayMode   = DisplayModeText
                pl_0C2.ViewObject.Justification = JustificationText
                pl_0C2.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C2.ViewObject.FontSize      = FontSizeText
                pl_0C2.Label      = nameLabel + "_Volume_Y_" + str(round(boundBoxLY,arondi))
                conteneurVol.addObject(pl_0C2)
        
                #pl_0C3 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=FreeCAD.Vector(oripl_X, oripl_Y, oripl_Z + (boundBoxLZ/2)))
                pl_0C3 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement = BDPl.multVec(App.Vector(0, 0, boundBoxLZ/2)))
                pl_0C3.ViewObject.DisplayMode   = DisplayModeText
                pl_0C3.ViewObject.Justification = JustificationText
                pl_0C3.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C3.ViewObject.FontSize      = FontSizeText
                pl_0C3.Label      = nameLabel + "_Volume_Z_" + str(round(boundBoxLZ,arondi))
                conteneurVol.addObject(pl_0C3)
    
    #    else:
    #        App.Console.PrintMessage("Not Volume BoundBox possible"+"\r\n")
        App.Console.PrintMessage("_____________________"+"\r\n")

    
        #####
        conteneurRectangle = []
        del conteneurRectangle[:]
        conteneurRectangle = App.activeDocument().addObject("App::DocumentObjectGroup",nameLabel + "_BoundBoxRectangle")
    
        if createDim == 1:    # conteneur dimension info
            conteneurInfo = []
            del conteneurInfo[:]
            conteneurInfo = App.activeDocument().addObject("App::DocumentObjectGroup",nameLabel + "_BoundBoxRectangle_Info")
        try:
            if (boundBoxLX and boundBoxLY) > 0.0:
                #pl_0 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,0.0))
                pl_0 = adjustedGlobalPlacement(objs[0], boundBoxLocation)
                double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLY,placement=pl_0,face=False,support=None) #OK
                double.Label = nameLabel + "_BoundBoxRectangle_Bo"
                FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
                conteneurRectangle.addObject(double)
    #        else:
    #            App.Console.PrintError("not value 0"+"\n")
    
            if createDim == 1:    # section create dimension info
                #pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=FreeCAD.Vector(pl_0.Base.x + (boundBoxLX/2), pl_0.Base.y, pl_0.Base.z))
                # XY -> XY
                pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_0.multVec(App.Vector(boundBoxLX/2, 0, 0)))
                pl_0C1.ViewObject.DisplayMode   = DisplayModeText
                pl_0C1.ViewObject.Justification = JustificationText
                pl_0C1.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C1.ViewObject.FontSize      = FontSizeText
                pl_0C1.Label      = nameLabel + "_Rectangle_Bo_0X_" + str(round(boundBoxLX,arondi))
                conteneurInfo.addObject(pl_0C1)
        
                #pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=FreeCAD.Vector(pl_0.Base.x, pl_0.Base.y + (boundBoxLY/2), pl_0.Base.z))
                pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_0.multVec(App.Vector(0., boundBoxLY/2, 0.)))
                pl_0C2.ViewObject.DisplayMode   = DisplayModeText
                pl_0C2.ViewObject.Justification = JustificationText
                pl_0C2.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C2.ViewObject.FontSize      = FontSizeText
                pl_0C2.Label      = nameLabel + "_Rectangle_Bo_0Y_" + str(round(boundBoxLY,arondi))
                conteneurInfo.addObject(pl_0C2)
    
        except:
            App.Console.PrintError("not done 0"+"\n")

        try:
            if (boundBoxLX and boundBoxLY) > 0.0:
                #pl_1 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z+boundBoxLZ), App.Rotation(0.0,0.0,0.0))
                pl_1 =adjustedGlobalPlacement(objs[0], boundBoxLocation + App.Vector(0,0,boundBoxLZ))
                double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLY,placement=pl_1,face=False,support=None) #Ok
                double.Label = nameLabel + "_BoundBoxRectangle_To"
                FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
                conteneurRectangle.addObject(double)
    #        else:
    #            App.Console.PrintError("not value 1"+"\n")
    
            if createDim == 1:    # section create dimension info
                #pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=FreeCAD.Vector(pl_1.Base.x + (boundBoxLX/2), pl_1.Base.y, pl_1.Base.z))
                #XY -> XY
                pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_1.multVec(App.Vector(boundBoxLX/2, 0, 0)))
                pl_0C1.ViewObject.DisplayMode   = DisplayModeText
                pl_0C1.ViewObject.Justification = JustificationText
                pl_0C1.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C1.ViewObject.FontSize      = FontSizeText
                pl_0C1.Label      = nameLabel + "_Rectangle_To_1X_" + str(round(boundBoxLX,arondi))
                conteneurInfo.addObject(pl_0C1)
        
                #pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=FreeCAD.Vector(pl_1.Base.x, pl_1.Base.y + (boundBoxLY/2), pl_1.Base.z))
                pl_0C2 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_1.multVec(App.Vector(0., boundBoxLY/2, 0)))

                pl_0C2.ViewObject.DisplayMode   = DisplayModeText
                pl_0C2.ViewObject.Justification = JustificationText
                pl_0C2.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C2.ViewObject.FontSize      = FontSizeText
                pl_0C2.Label      = nameLabel + "_Rectangle_To_1Y_" + str(round(boundBoxLY,arondi))
                conteneurInfo.addObject(pl_0C2)
    
        except:
            App.Console.PrintError("not done 1"+"\n")

        try:
            if (boundBoxLX and boundBoxLZ) > 0.0:
                #pl_2 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,90))
                pl_2 = pl_0.multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(0.0,0.0,90)))
                double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLZ,placement=pl_2,face=False,support=None) #Ok
                double.Label = nameLabel + "_BoundBoxRectangle_Fr"
                FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
                conteneurRectangle.addObject(double)
    #        else:
    #            App.Console.PrintError("not value 2"+"\n")
    
            if createDim == 1:    # section create dimension info
                #pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=FreeCAD.Vector(pl_2.Base.x + (boundBoxLX/2), pl_2.Base.y, pl_2.Base.z))
                #XZ -> XY
                pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_2.multVec(App.Vector(boundBoxLX/2, 0, 0)))
                pl_0C1.ViewObject.DisplayMode   = DisplayModeText
                pl_0C1.ViewObject.Justification = JustificationText
                pl_0C1.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C1.ViewObject.FontSize      = FontSizeText
                pl_0C1.Label      = nameLabel + "_Rectangle_Fr_2X_" + str(round(boundBoxLX,arondi))
                conteneurInfo.addObject(pl_0C1)
       
                #pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=FreeCAD.Vector(pl_2.Base.x, pl_2.Base.y, pl_2.Base.z + (boundBoxLZ/2)))
                pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_2.multVec(App.Vector(0, boundBoxLZ/2, 0)))
                pl_0C2.ViewObject.DisplayMode   = DisplayModeText
                pl_0C2.ViewObject.Justification = JustificationText
                pl_0C2.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C2.ViewObject.FontSize      = FontSizeText
                pl_0C2.Label      = nameLabel + "_Rectangle_Fr_2Z_" + str(round(boundBoxLZ,arondi))
                conteneurInfo.addObject(pl_0C2)
    
        except:
            App.Console.PrintError("not done 2"+"\n")

        try:
            if (boundBoxLX and boundBoxLZ) > 0.0:
                #pl_3 = App.Placement(App.Vector(oripl_X,oripl_Y+boundBoxLY,oripl_Z), App.Rotation(0.0,0.0,90))
                pl_3 = adjustedGlobalPlacement(objs[0], boundBoxLocation+App.Vector(0, boundBoxLY, 0)).multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(0.0,0.0,90)))
                double = Draft.makeRectangle(length=boundBoxLX,height=boundBoxLZ,placement=pl_3,face=False,support=None) #Ok
                double.Label = nameLabel + "_BoundBoxRectangle_Re"
                FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
                conteneurRectangle.addObject(double)
    #        else:
    #            App.Console.PrintError("not value 3"+"\n")
    
            if createDim == 1:    # section create dimension info
                #XZ -> XY
                pl_0C1 = Draft.make_text([str(round(boundBoxLX,arondi))],placement=pl_3.multVec(App.Vector(boundBoxLX/2, 0, 0)))
                pl_0C1.ViewObject.DisplayMode   = DisplayModeText
                pl_0C1.ViewObject.Justification = JustificationText
                pl_0C1.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C1.ViewObject.FontSize      = FontSizeText
                pl_0C1.Label      = nameLabel + "_Rectangle_Re_3X_" + str(round(boundBoxLX,arondi))
                conteneurInfo.addObject(pl_0C1)
        
                pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_3.multVec(App.Vector(0, boundBoxLZ/2, 0)))
                pl_0C2.ViewObject.DisplayMode   = DisplayModeText
                pl_0C2.ViewObject.Justification = JustificationText
                pl_0C2.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C2.ViewObject.FontSize      = FontSizeText
                pl_0C2.Label      = nameLabel + "_Rectangle_Re_3Z_" + str(round(boundBoxLZ,arondi))
                conteneurInfo.addObject(pl_0C2)
    
        except:
            App.Console.PrintError("not done 3"+"\n")

        try:
            if (boundBoxLY and boundBoxLZ) > 0.0:
                #pl_4 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
                pl_4 = pl_0.multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(90,0,90)))
                double = Draft.makeRectangle(length=boundBoxLY,height=boundBoxLZ,placement=pl_4,face=False,support=None) #Ok
                double.Label = nameLabel + "_BoundBoxRectangle_Le"
                FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
                conteneurRectangle.addObject(double)
    #        else:
    #            App.Console.PrintError("not value 4"+"\n")
    
            if createDim == 1:    # section create dimension info
                #pl_0C1 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=FreeCAD.Vector(pl_4.Base.x, pl_4.Base.y + (boundBoxLY/2), pl_4.Base.z))
                #YZ ->XY
                pl_0C1 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_4.multVec(App.Vector(boundBoxLY/2, 0., 0.)))
                pl_0C1.ViewObject.DisplayMode   = DisplayModeText
                pl_0C1.ViewObject.Justification = JustificationText
                pl_0C1.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C1.ViewObject.FontSize      = FontSizeText
                pl_0C1.Label      = nameLabel + "_Rectangle_Le_4Y_" + str(round(boundBoxLY,arondi))
                conteneurInfo.addObject(pl_0C1)
        
                #pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=FreeCAD.Vector(pl_4.Base.x, pl_4.Base.y, pl_4.Base.z + (boundBoxLZ/2)))
                pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_4.multVec(App.Vector(0., boundBoxLZ/2, 0)))
                pl_0C2.ViewObject.DisplayMode   = DisplayModeText
                pl_0C2.ViewObject.Justification = JustificationText
                pl_0C2.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C2.ViewObject.FontSize      = FontSizeText
                pl_0C2.Label      = nameLabel + "_Rectangle_Le_4Z_" + str(round(boundBoxLZ,arondi))
                conteneurInfo.addObject(pl_0C2)
    
        except:
            App.Console.PrintError("not done 4"+"\n")

        try:
            if (boundBoxLY and boundBoxLZ) > 0.0:
                #pl_5 = App.Placement(App.Vector(oripl_X+boundBoxLX,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
                pl_5 = adjustedGlobalPlacement(objs[0], boundBoxLocation+App.Vector(boundBoxLX,0,0)).multiply(App.Placement(App.Vector(0.,0.,0.),App.Rotation(90,0.0,90)))
                double = Draft.makeRectangle(length=boundBoxLY,height=boundBoxLZ,placement=pl_5,face=False,support=None) #Ok
                double.Label = nameLabel + "_BoundBoxRectangle_Ri"
                FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
                conteneurRectangle.addObject(double)
    #            else:
    #                App.Console.PrintError("not value 5"+"\n")
    
            if createDim == 1:    # section create dimension info
                #YZ-> XY
                pl_0C1 = Draft.make_text([str(round(boundBoxLY,arondi))],placement=pl_5.multVec(App.Vector(boundBoxLY/2, 0, 0)))
                pl_0C1.ViewObject.Justification = JustificationText
                pl_0C1.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C1.ViewObject.FontSize      = FontSizeText
                pl_0C1.Label      = nameLabel + "_Rectangle_Ri_5Y_" + str(round(boundBoxLY,arondi))
                conteneurInfo.addObject(pl_0C1)
        
                pl_0C2 = Draft.make_text([str(round(boundBoxLZ,arondi))],placement=pl_5.multVec(App.Vector(0, boundBoxLZ/2, 0 )))
                pl_0C2.ViewObject.DisplayMode   = DisplayModeText
                pl_0C2.ViewObject.Justification = JustificationText
                pl_0C2.ViewObject.TextColor     = (TextColorText_R, TextColorText_G, TextColorText_B)
                pl_0C2.ViewObject.FontSize      = FontSizeText
                pl_0C2.Label      = nameLabel + "_Rectangle_Ri_5Z_" + str(round(boundBoxLZ,arondi))
                conteneurInfo.addObject(pl_0C2)
    
        except:
            App.Console.PrintError("not done 5"+"\n")
    
        #####
        App.ActiveDocument.recompute()
    except Exception:
        App.Console.PrintError("Bad selection"+"\n")
else:
    App.Console.PrintMessage("Select an object !"+"\n")


Version

Version: 0.12 Date 2021/07/10: upgrade by edwilliams16 to handle objects in nested part containers. FCInfo CG of assemblies corrected the global placement, thanks edwilliams16

def adjustedGlobalPlacement(obj, locVector):
    '''find global placement to make locVector the local origin with the correct orientation'''
    try:
        objectPlacement = obj.Shape.Placement
        objectGlobalPlacement = obj.getGlobalPlacement()
        locPlacement = App.Placement(locVector, App.Rotation(App.Vector(1,0,0),0))
        return objectGlobalPlacement.multiply(objectPlacement.inverse()).multiply(locPlacement)
    except Exception:
        locPlacement = App.Placement(App.Vector(0,0,0), App.Rotation(0,0,0), App.Vector(0,0,0))
        return locPlacement

Version: 0.11 Date: 2019/05/29: "nameLabel = str(unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore'))" instead "def()"

Version: 0.10 Date: 2019/05/23 upgrade > 0.19 and supp the "éçà.." with def() not encode()....

Version: 0.9 le 2018-10-12: add test > 17

if int(FreeCAD.Version()[1]) > 17:      # Version de FreeCAD
    DisplayModeText   = str(u"2D text") # available : u"2D text" or u"3D text" 
else:
    DisplayModeText   = str(u"Screen")  # available : u"Screen" or u"World"

Version: 0.8 Date: 05/10/2018: upgrade the ver 0.8 compatible with FC 0.17 (getGlobalPlacement)

Version: 0.7 Date: 28/01/2018: correct error with label accent "nameLabel = unicodedata.normalize('NFKD', nameLabel).encode('ascii','ignore')"

Version: 0.6 Date: 08/08/2017: add text info dimension , contener for rectangles, info rectangles, info volume, add section configuration color , label object selected

Version: 0.5 Date: 08/05/2017 : upgrade now accept the "mesh" and "Points" thanks wmayer Makro Bounding-Box für STL importierte Teile und für Punktewolken

Version: 0.4 Date: 04/06/2016 : test if value = 0 then not create boundbox (ex: object Draft)