Macro Rotate To Point: Difference between revisions

From FreeCAD Documentation
m (minor)
(Marked this version for translation)
 
(35 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<languages/>
<languages/>
<translate>
<translate>

<!--T:1-->
<!--T:1-->
{{Macro
{{Macro
|Name=Macro Rotate To Point
|Name=Macro Rotate To Point
|Icon=Macro_Rotate_To_Point.svg
|Icon=Macro_Rotate_To_Point.svg
|Description={{ColoredText|#ff0000|#ffffff|Updated version of macro modified the GUI to improve HiDPI support (QGridLayout). Run only FC v0.18 or higher (supporting Qt5 and PySide2)}} <br/> <br/> Macro for rotate an object on itself with the axis of rotation the: boundbox center, center of mass, direction of wire, or last point clicked. You must save in a file all coordinate worked and save it in a file "Coordinate [(0.06,1.30,0.0),(85.0,0.0,0.0)]," or in a complete macro for create one animation<br/><br/>For the previous version (Qt4) see [https://gist.githubusercontent.com/mario52a/2fc48333deca5a31e6232c29a9db5e4c/raw/9231d5b1d218357305cc0404e46bf6c107509a0e/Macro%2520Rotate%2520To%2520Point.FCMacro Macro_Rotate_To_Point] and install it manually.
|Description=Macro to rotate an object on itself with the axis of rotation the: boundbox center, center of mass, direction of wire, or last point clicked. You must save in a file all coordinate worked and save it in a file "Coordinate [(0.06,1.30,0.0),(85.0,0.0,0.0)]," or in a complete macro with different options (Create serial image) for create one animation, increase/decrease, pause, yoyo ....
|Author=Mario52
|Author=Mario52
|Version=00.06
|Version=00.11
|Date=2021/01/12
|Date=2022/10/17
|FCVersion=0.18+
|FCVersion=0.19 and more
|Download=[https://www.freecadweb.org/wiki/images/d/d1/Macro_Rotate_To_Point.svg ToolBar Icon]
|Download=[https://www.freecadweb.org/wiki/images/d/d1/Macro_Rotate_To_Point.svg ToolBar Icon]
}}
}}
Line 16: Line 17:


<!--T:3-->
<!--T:3-->
Macro to rotate an object on itself with the axis of rotation the: boundbox center, center of mass, direction, path of wire, or last point clicked. You must save in a file all coordinate worked and save it in a file "Coordinate [(0.06,1.30,0.0),(85.0,0.0,0.0)]," </br>or in a complete macro with different options (Create serial image) for create one animation, increase/decrease, pause, yoyo ....
Macro to rotate an object on itself with the axis of rotation being either the:

* boundbox center

* center of mass
</translate>
* direction of wire
{{Codeextralink|https://gist.githubusercontent.com/mario52a/2fc48333deca5a31e6232c29a9db5e4c/raw/d9419d4bb13e36940eb2f56c3c469ea4182827ee/Macro%2520Rotate%2520To%2520Point.FCMacro}}
* last point clicked
<translate>


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


<!--T:5-->
<!--T:5-->
# Download the macro from the [[Addon Manager]]
# Download the macro from the [[Std_AddonMgr|Addon Manager]]
# Execute the macro
# Execute the macro
# Select one object
# Select one object
Line 31: Line 33:


</translate>
</translate>
[[File:Macro Rotate To Point 00.png|Interface Rotate to point ]]
[[File:Macro_Rotate_To_Point_00.png|Interface Rotate to point]]
{{clear}}
<translate>
<translate>

===[1] Position Rotation=== <!--T:42-->

<!--T:43-->
''First operation''

<!--T:44-->
[[File:Macro_Rotate_To_Point_Position-Rotation00.png| [1] Position Rotation]]

<!--T:45-->
*{{CheckBox|Translation}}: If this checkBox is {{CheckBox|TRUE|checked}} the rotation is disabled, the object placement is done on the axis selected.

<!--T:46-->
''The SpinBox {{SpinBox|1,00000 Degrees}} is reinitialized to {{incode|0.0}} and coloured in red''

<!--T:47-->
*The time passed with your favourite macro is displayed.

===[2] Translation Rotation=== <!--T:48-->

<!--T:49-->
''Second operation''

<!--T:50-->
[[File:Macro_Rotate_To_Point_Translation-Rotation00.png|[2]Translation Rotation]]


===Point Rotation=== <!--T:6-->
===Point Rotation=== <!--T:6-->
Line 51: Line 77:
*Rotation(X) Roll: Roll axis
*Rotation(X) Roll: Roll axis
*Rotation(D) Direction: Rotate around line, wire selected
*Rotation(D) Direction: Rotate around line, wire selected
*Follow the path: Follow the path created by the wire, line, edge.
**1: Select the object
**2: Select the path

<!--T:51-->
''The SpinBox {{SpinBox|1,00000 Degrees}} is reinitialized to {{incode|0.0}} and coloured in red''


===Coordinates Point clicked=== <!--T:24-->
===Coordinates Point clicked=== <!--T:24-->


<!--T:25-->
<!--T:25-->
[[File:Macro_Rotate_To_Point_Coordinate-On-Point-Clicked_00.png|Rotate To Point Coordinate-On-Point-Clicked]]
*DoubleSpinBox: Coordinate X on mouse click (modifiable only with the mode "Point Clicked")
*DoubleSpinBox: Coordinate X on mouse click (modifiable only with the mode "Point Clicked")
*DoubleSpinBox: Coordinate Y on mouse click (modifiable only with the mode "Point Clicked")
*DoubleSpinBox: Coordinate Y on mouse click (modifiable only with the mode "Point Clicked")
*DoubleSpinBox: Coordinate Z on mouse click (modifiable only with the mode "Point Clicked")
*DoubleSpinBox: Coordinate Z on mouse click (modifiable only with the mode "Point Clicked")


===Work=== <!--T:26-->
===[3] Work (Box : Cube)=== <!--T:26-->

<!--T:52-->
''Third operation''

<!--T:55-->
[[File:Macro Rotate To Point Work 00.png|Macro Rotate To Point Work]]


<!--T:27-->
<!--T:27-->
*{{CheckBox|Translation}}: If this checkBox is {{CheckBox|TRUE|checked}} the rotation is disabled, the object placement is done on the axis selected.
*{{CheckBox|View}}: If checked, the view return on latest view of the object selected (work with comboBox below it) and all parameters restored.
*{{Button|Point}}: One point is created for visualise the point rotation axis: red X, green Y, blue Z
*{{Button|Point}}: One point is created for visualise the point rotation axis: red X, green Y, blue Z.
*{{Button|Center}}: One point is created on center of circle.
*Line Edit: The line edit displays the original coordinate to axis selected + the input data given in the spinBox
*{{ComboBox|Box}}: List of all objects used. The choice of the object here, the zoom ''(if checkBox view is checked)'' is returned and all parameters restored.
*{{SpinBox|0,0000}}: Enter the modification
*{{ComboBox|0}}: Select one predefined value.
*{{KEY|Apply}}: Apply the modification to the object
*{{ComboBox|1.0}}: Select the saved value used.
*{{Button|- Invert}}: Invert the sign Positif/Negatif of the value displayed.
*{{SpinBox|1,00000 Degrees}}: Select the value.
*{{KEY|Apply}}: Apply the modification to the object.
*Line Edit: The line edit displays the original coordinate to axis selected + the input data given in the spinBox.
*The coordinate is displayed
*The coordinate is displayed


===Data=== <!--T:28-->
===Data to save=== <!--T:28-->

<!--T:56-->
[[File:Macro Rotate To Point Data-To-Save 00.png|Rotate To Point Data-To-Save]]


<!--T:29-->
<!--T:29-->
*Window for display the coordinates memorized
*Window for display the coordinates stored.
*{{Button|Clear}}: Delete and clean the text editor.
*{{Button|Delete}}: Delete the selected line in the window.
*{{CheckBox|Memo on Click}}: If it is checked, the placement is automatically stored in the window with the "Apply" button.
*{{Button|Memorize}}: Store and display the coordinate in the window, the number of coordinate stored is displayed on this button.
*{{Button|Save}}: Save the data in file
*{{Button|Save}}: Save the data in file
*{{Button|Clear}}: Delete and clean the text editor
*{{Button|Delete}}: Delete the selected line
*{{Button|Memorize}}: Memorize and display the coordinate
*{{CheckBox|Macro}}:
*{{CheckBox|Macro}}:
**Mode normal {{CheckBox|Macro}} the coordinate is saved in this mode : '''[(0.06,1.30,0.0),(85.0,0.0,0.0)],'''
**Mode normal {{CheckBox|Macro}} the coordinate is saved in this mode : {{incode|["Body004001",(0.0,0.0,-1.5),(0.0,0.0,0.0)],}}
**Mode macro {{CheckBox|TRUE|0,0 Coordinate}} the coordinate is saved in a complete macro directly in your macros directory with the same name of the document extention .FCMacro
**Mode macro {{CheckBox|TRUE|0,0 Coordinate}} the coordinate is saved (one object or many objects worked)</br> in a complete macro directly in your macros directory with the same name of the document with extension .FCMacro
*** '''Options of the macro'''
*** '''Options of the macro'''
***'''__pompe____engrenage__''' : Name of document
***'''__pompe____engrenage__''' : Name of document
***'''__22 Coordinates__''' : number of coordinates
***'''__22 Coordinates__''' : number of coordinates
***'''Type Key Q to Quit''' : Quit the macro
***'''Type Key Q to Quit''' : Quit the macro
***'''Type Key A to Create serial image''' : for create serial usage to create Animate GIF (with Gimp or other)
***'''Type Key D to Decrease speed''' : Decrease the speed of the animation
***'''Type Key D to Decrease speed''' : Decrease the speed of the animation
***'''Type Key I to Increase speed''' : Increase the speed of the animation
***'''Type Key I to Increase speed''' : Increase the speed of the animation
***'''Type Key P to Pause/Continue or key RETURN or ESCAPE''' : Pause / Anime
***'''Type Key P to Pause/Continue or key RETURN or ESCAPE''' : Pause / Anime
***'''Type Key S to Step by Step (key RETURN or ESCAPE to continue)''' : Step by Step
***'''Type Key S to Step by Step (key RETURN or ESCAPE to continue)''' : Step by Step
***'''Type Key M for this message''' : Display this memo
***'''Type Key V to reVerse''' : reVerse the video
***'''Type Key Y to YoYo''' : begin to end reverse end to begin
***'''Type Key M for this message''' : Display this Memo
***For use this options click mouse in the 3D view and type the key desidered
***____________________________
***____________________________
*{{CheckBox|Memo on Click}}:
**Mode normal {{CheckBox|Memo on Click}} : The data is not saved on window, you must push the {{Button|Memo (2)}} button for save the coordinate
**Mode normal {{CheckBox|Memo on Click}} : The data is not saved on window, you must push the {{Button|Memo (2)}} button for save the coordinate
**Mode Memo on Click {{CheckBox|TRUE|Memo on Demand}} : The data is automaticly saved with all click op the {{Button|Apply}} button
**Mode Memo on Click {{CheckBox|TRUE|Memo on Demand}} : The data is automaticly saved with all click op the {{Button|Apply}} button
*{{Button|Copy}}: Memorize the content of the window in a Rotate_To_Point format : {{incode|["Body004001",(0.0,0.0,-1.5),(0.0,0.0,0.0)],}}


===Command=== <!--T:30-->
===Command=== <!--T:30-->

<!--T:57-->
[[File:Macro Rotate To Point Command 00.png|Rotate To Point Command]]


<!--T:31-->
<!--T:31-->
*{{KEY|Quit}}: Quit the macro
*{{KEY|Quit}}: Quit the macro
*{{KEY|Original}}: After modifying the data of the object you can return to the original placement, If you have not deselected the current object.
*{{KEY|Original}}: After modifying the data of the object you can return to the original placement, If you have not deselected the current object.
*{{KEY| 0,0,0 }}: This option places the object in base coordinate {{incode|0, 0, 0}}
*{{KEY| 0,0,0 }}: This option places the object in base coordinate {{incode|0, 0, 0}}.
*{{KEY|Reset}}: Reset the data in the macro and deselect the current object (same mouse click in the [[3D view]])
*{{KEY|Reset}}: Reset the data in the macro and deselect the current object.
</translate>
<translate>
==Script== <!--T:7-->
</translate>


<!--T:53-->
ToolBar Icon PNG [[File:Macro Rotate To Point.png]] SVG [[Image:Macro_Rotate_To_Point.svg]]
ToolBar PNG Icon [[File:Macro_Rotate_To_Point.png]] and ToolBar SVG Icon [[Image:Macro_Rotate_To_Point.svg]]


==Example== <!--T:9-->
'''Macro_Rotate_To_Point.FCMacro'''


</translate>
{{MacroCode|code=
[[File:Macro Rotate To Point 01.gif]]
# -*- coding: utf-8 -*-
<translate>
from __future__ import unicode_literals
"""
***************************************************************************
* Copyright (c) 2017 2018 2019 2020 2021 <mario52> *
* *
* This file is a supplement to the FreeCAD CAx development system. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License (LGPL) *
* as published by the Free Software Foundation; either version 2 of *
* the License, or (at your option) any later version. *
* for detail see the LICENCE text file. *
** **
* Use at your own risk. The author assumes no liability for data loss. *
* It is advised to backup your data frequently. *
* If you do not trust the software do not use it. *
** **
* *
* This software 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 macro; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
***************************************************************************
* WARNING! All changes in this file will be lost and *
* may cause malfunction of the program *
***************************************************************************
"""
#
#
#OS: Windows 10 (10.0)
#Word size of OS: 64-bit
#Word size of FreeCAD: 64-bit
#Version: 0.19.23546 (Git)
#Build type: Release
#Branch: master
#Hash: 6b017f9a16b15b0e628c8d874c4058442dee5548
#Python version: 3.6.8
#Qt version: 5.12.1
#Coin version: 4.0.0a
#OCC version: 7.3.0
#Locale: French/Mars (fr_Ma)
#
#
__title__ = "Rotate_To_Point"
__author__ = "Mario52"
__url__ = "https://www.freecadweb.org/"
__Wiki__ = "https://www.freecadweb.org/wiki/Macro_Rotate_To_Point"
__version__ = "00.06"
__date__ = "2021/01/12" #YYYY/MM/DD
#


==Links== <!--T:41-->
import WebGui
#WebGui.openBrowser("http://www.freecadweb.org/")


<!--T:10-->
import PySide2
The forum [http://forum.freecadweb.org/viewtopic.php?f=8&t=20925 feature req: placement - rotate part around its midpoint]
from PySide2 import (QtWidgets, QtCore, QtGui)
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *
#from PySide2.QtWidgets import (QWidget, QApplication, QSlider, QGraphicsView, QGraphicsScene, QVBoxLayout, QStyle, QListWidget)
#from PySide2.QtCore import QDate
#from PySide2.QtGui import (QPainter, QColor, QIcon, QBrush, QPalette)
from PySide2.QtSvg import *


<!--T:11-->
import Draft, Part, PartGui, FreeCADGui, FreeCAD
My macro on Gist [https://gist.github.com/mario52a mario52a]
from FreeCAD import Base
import DraftVecUtils
#import time


==Version== <!--T:12-->
Gui = FreeCADGui
App = FreeCAD


<!--T:54-->
global ui ; ui = ""
2022/10/17 Version=00.11 : new organization GUI, Follow the path, View on object, Button Copy, adding menu Image on macro saved, add "QtWidgets.QScrollArea()"
global sourisPass ; sourisPass = 0
global positionMouse ; positionMouse = ""


<!--T:38-->
global originalObject; originalObject = ""
2021/03/08 Version=00.10 : adding zoom on object clicked, memory value, imposted values
global myObject ; myObject = ""
global originalPlacement; originalPlacement = ""
global valeur ; valeur = 0.0


<!--T:37-->
global axisX ; axisX = 0.0
2021/02/25 Version=00.09 : correct the macro : cause multi object possible
global axisY ; axisY = 0.0
global axisZ ; axisZ = 0.0


</translate>
global posX ; posX = 0.0
{{Code|
global posY ; posY = 0.0
App.ActiveDocument.getObject(p[0]).Placement
global posZ ; posZ = 0.0
}}
<translate>
<!--T:58-->
instead
</translate>
{{Code|
myObject.Placement
}}
<translate>


<!--T:36-->
global rotAngleX ; rotAngleX = 0.0
2021/02/22 Version=00.08c : correct the center facePoint (19h26 Paris)
global rotAngleY ; rotAngleY = 0.0
global rotAngleZ ; rotAngleZ = 0.0


<!--T:35-->
global saveOnDisk ; saveOnDisk = []
2021/02/22 Version=00.08b : correct the center facePoint (17h23 Paris)
global saveListView ; saveListView = ""
global memorySelected; memorySelected = []
global countMemory ; countMemory = 0


<!--T:34-->
##path###########################################################################
2021/02/22 Version=00.08 : adding save macro with multi objects moved
global path, path2 #
#path = FreeCAD.ConfigGet("AppHomePath") # path FreeCAD installation
#path = FreeCAD.ConfigGet("UserAppData") # path FreeCAD User data
#path = "your path" # your directory path
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path
path = param.GetString("MacroPath","") + "/" # macro path
path = path.replace("\\","/") # convert the "\" to "/"
#print( "Path for the icons : " , path ) #
#################################################################################


<!--T:33-->
global pathFile
2021/01/24 Version=00.07 : adding option R: reverse
#### Configuration ##############################################################
pathFile = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__ ).GetString("setLastPath")
if pathFile == "":
pathFile = path
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetString("setLastPath",pathFile)
####
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetString("Version",__version__ + " (" + __date__ + ")")
#### Configuration ##############################################################

Quit_Icon = [
"24 24 3 1",
" c None",
". c #FFFFFF",
"+ c #CC0000",
" .... ",
"++++++++++....++++++++++",
"+.......++....++.......+",
"+.......++....++.......+",
"+.......++....++.......+",
"+...++++++....++++++...+",
"+...++++++....++++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+......................+",
"+......................+",
"+......................+",
"++++++++++++++++++++++++"
]

boundBox_Center_Icon = [
"24 24 8 1",
" c None",
". c #284871",
"+ c #234C86",
"@ c #314B64",
"# c #EF2929",
"$ c #4A74A4",
"% c #4478AD",
"& c #4E9A06",
" ",
" # ",
" # ",
" # ",
" &&&&&# ",
" & #&&&&&&& ",
" & +#.. && ",
" &&&&&+%#%%. & & ",
" & ++&&&&&&& & ",
" & +$$$$$$&+@ & ",
" & +%$$$$$$&+@ & ",
"####&###$$$$$+&+####### ",
" & +%$$$$++&+@ & ",
" & +%$$$+++&+@ & ",
" & +$$++++&@ & ",
" & ++++++&@ & ",
" & @@@@@& & ",
" & # & & ",
" &&&&& # &&& ",
" &&&&&& ",
" # ",
" # ",
" # ",
" "
]

centerMass_Icon = [
"24 24 9 1",
" c None",
". c #000100",
"+ c #CD0000",
"@ c #6B6014",
"# c #B0A22C",
"$ c #D5B716",
"% c #E9D235",
"& c #F7E66C",
"* c #FBF4BC",
" ",
" ",
" ",
" ",
" ...... ",
" ..#%%%%#.. ",
" .@&&&%%%%%@. ",
" .@&**&%%%%%%@. ",
" .&***&%%%%%%%. ",
" .#&**&%%+%%%%%#. ",
" .%&&&%%++%%%$$%. ",
" .%%%%+++++$$$$$. ",
" .%%%%%+++++$$$$. ",
" .%%%%$$++$$$$$$. ",
" .#%$$$$+$$$$$$#. ",
" .%$$$$$$$$$$%. ",
" .@%$$$$$$$$$@. ",
" .@%$$$$$$%@. ",
" ..#$$$$#.. ",
" ...... ",
" ",
" ",
" ",
" "
]

point_Clicked_Icon = [
"24 24 7 1",
" c None",
". c #730000",
"+ c #9F0000",
"@ c #E90000",
"# c #C39F03",
"$ c #ECD309",
"% c #FBE851",
" ",
" ##### ",
" #%%%%%# ",
" #%%%%%%$# ",
" #%%%%%$$$$# ",
" #%%%%$$$$$# ",
" #%%%+.$$$$# ",
" #%%%++.$$$# ",
" #%%+@+.$# ",
" #%%+@@+.# ",
" ##+@@@+. ",
" +@@@@+. ",
" +@@@@@+. ",
" +@@@@@@+. ",
" +@@@@@@@.. ",
" +@@@@@@@@.. ",
" +@@@@@@@@@.. ",
" +@@@@@@+.... ",
" +@@@@@+ ",
" +@@++@@. ",
" +@+. .@@. ",
" ++. .@. ",
" .+.. ",
" .. "
]

axis_X_Icon = [
"24 24 6 1",
" c None",
". c #000000",
"+ c #A40000",
"@ c #EE2A2A",
"# c #729FCF",
"$ c #B9BCB5",
" $$ $$$$ ",
" $$$$ $ $ ",
" $$$$$$ $ ",
" $$$$$$ $ ",
" $$$$$$$$ $$$ ",
" $$$$ ",
" $$$$ ",
" $$$$ ",
" $$$$ ",
" $$$$ $$ $$",
" $$##$$ $$ $$",
" . . $####$ $$$ ",
" ... +####$ $$ ",
" .. +@####$$ $ ",
" . ... +@@@+$$$$$ $$ ",
" +@@@+ $$$$$ ",
" +@@@+ $$$$$ ",
" +++@@@+ $$$$$$$ ",
" +@@@@+ $$$$$$ ",
" +@@@+ $$$$$ ",
" +++++ $$$$$ ",
" ",
" ",
" "
]

axis_Y_Icon = [
"24 24 7 1",
" c None",
". c #030303",
"+ c #4E9A06",
"@ c #729FCF",
"# c #B9BCB5",
"$ c #BABDB6",
"% c #8AE134",
" $$ #### ",
" $$$$ # # ",
" $$$$$$ # ",
" $$$$$$ # ",
" $$$$$$$$ ### ",
" $$$$ ",
" $$$$ ",
" $$$$ ",
" $$$$ ",
" $$$$ .. ..",
" $$@@$$ .. ..",
" # # $@@@@$ ... ",
" ### $@@@@+ .. ",
" ## $$@@@@%+ . ",
" # ### $$$$$+%%%+ .. ",
" $$$$$ +%%%+ ",
" $$$$$ +%%%+ ",
" $$$$$$$ +%%%+++ ",
" $$$$$$ +%%%%+ ",
" $$$$$ +%%%+ ",
" $$$$$ +++++ ",
" ",
" ",
" "
]

axis_Z_Icon = [
"24 24 6 1",
" c None",
". c #000000",
"+ c #204A87",
"@ c #1D89B6",
"# c #729FCF",
"$ c #B9BCB5",
" ++ ... ",
" +@@+ . ",
" +@@@@+ . ",
" +@@@@+ . ",
" +++@@+++ ... ",
" +@@+ ",
" +@@+ ",
" +@@+ ",
" +@@+ ",
" +@@+ $$ $$",
" ++##++ $$ $$",
" $ $ +####+ $$$ ",
" $$$ $####$ $$ ",
" $$ $$####$$ $ ",
" $ $$$ $$$$$$$$$$ $$ ",
" $$$$$ $$$$$ ",
" $$$$$ $$$$$ ",
" $$$$$$$ $$$$$$$ ",
" $$$$$$ $$$$$$ ",
" $$$$$ $$$$$ ",
" $$$$$ $$$$$ ",
" ",
" ",
" "
]

direction_Icon = [
"24 24 6 1",
" c None",
". c #000000",
"+ c #A40000",
"@ c #EE2A2A",
"# c #565854",
"$ c #729FCF",
" ",
" ",
" +++++ ",
" +@@+ ",
" +@@@+ ",
" +@@@++ ",
" +@@@+ + ",
" +@@@+ ",
" +@@@+ ",
" +@@@+ ",
" +@@@+ ",
" +@@@+ ",
" +@@@+ ",
" +@@@+ ",
" +@@@+ ",
" +@@@+ ",
" + +@@@+ ",
" ++@@@+ ",
" +@@@+ ",
" +@@+ ",
" +++++ ",
" ",
" ",
" "
]

point_Icon = [
"24 24 8 1",
" c None",
". c #000100",
"+ c #B0A22C",
"@ c #E9D235",
"# c #6B6014",
"$ c #F7E66C",
"% c #FBF4BC",
"& c #D5B716",
" ",
" ",
" ",
" ",
" ...... ",
" ..+@@@@+.. ",
" .#$$$@@@@@#. ",
" .#$%%$@@@@@@#. ",
" .$%%%$@@@@@@@. ",
" .+$%%$@@@@@@@@+. ",
" .@$$$@@@@@&&&&&. ",
" .@@@@@@@&&&&&&&. ",
" .@@@@@&&&&&&&&&. ",
" .@@@@&&&&&&&&&&. ",
" .+@@&&&&&&&&&&+. ",
" .@&&&&&&&&&&&. ",
" .#&&&&&&&&&&#. ",
" .#&&&&&&&&#. ",
" ..+&&&&+.. ",
" ...... ",
" ",
" ",
" ",
" "
]

apply_Icon = [
"24 24 3 1",
" c None",
". c #4E9A06",
"+ c #FFFFFF",
" ",
" ",
" ",
" . ",
" .+. ",
" .+.+. ",
" .+...+. ",
" .+.....+. ",
" . .+.......+.",
" .+. .+.......+. ",
" .+.+. .+.......+. ",
" .+...+. .+.......+. ",
" .+.....+.+.......+. ",
".+.......+.......+. ",
" .+.............+. ",
" .+...........+. ",
" .+.........+. ",
" .+.......+. ",
" .+.....+. ",
" .+...+. ",
" .+.+. ",
" .+. ",
" . ",
" "
]

quit_Icon = [
"24 24 3 1",
" c None",
". c #FFFFFF",
"+ c #CC0000",
" .... ",
"++++++++++....++++++++++",
"+.......++....++.......+",
"+.......++....++.......+",
"+.......++....++.......+",
"+...++++++....++++++...+",
"+...++++++....++++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+......................+",
"+......................+",
"+......................+",
"++++++++++++++++++++++++"
]

save_Icon = [
"24 24 9 1",
" c None",
". c #A30500",
"+ c #5D5F5C",
"@ c #3967A0",
"# c #4B9A00",
"$ c #7E9BBD",
"% c #A9ABA8",
"& c #C7C9C6",
"* c #DCDEDB",
" ",
" @@@@@ ",
" @@$$$$$@ ",
" @$$$$$$$@ ",
" @@@@@@$@$$@ ",
" @$@@@ ",
" +%&&&@$@@@@&%%% ",
" +*@@@$@@@@@@@@&% ",
" +%*@@@@@@@@@@@@*&+ ",
" +***@@@@@@@@@@***+ ",
" +%***&@@@@@@@@&****+ ",
" +****&&@@@@@@&&****+ ",
" +***&&&&@@@@&&&&***+ ",
" +%***&&&&&@@&&&&&****+ ",
" +***&&&&&&&&&&&&&&***+ ",
" %********************+ ",
" %********************+ ",
" %&&&&&&&&&&&&&&&&&&&&+ ",
" %&%%%%%%%%%%%%%%%%%%%+ ",
" %&%%%%%%%%%%%%%%%%%%%+ ",
" %&%&&&%%%%%%%@%%#%%.%+ ",
" %%%%%%%%%%%%%%%%%%%%%+ ",
" ++++++++++++++++++++++ ",
" "
]

clear_Icon = [
"24 24 9 1",
" c None",
". c #000200",
"+ c #8B0606",
"@ c #875209",
"# c #E3383A",
"$ c #C19916",
"% c #C4A163",
"& c #E2C928",
"* c #E4D05A",
" @@@ ",
" @%%%@ ",
" @%*@@ ",
" @%@*%@ ",
" @%$$%@ ",
" @%%$%%@ ",
" @%$$$*@ ",
" @$**+++ ",
" @*%+##+. ",
" ++##+*$ ",
" +#++****$ ",
" ++****&**$ ",
" &**&*&&&*$ ",
" &*&&&*&$&*$ ",
" $*&*&$&&$$*$ ",
" $*&$&*$*&*$*$ ",
" *&$$&&$&&&&*$ ",
" $*&$&**$$**@ ",
" $*&$&****&$ ",
" $*$***$$@ ",
" $***$@ @ ",
" $@$@ ",
" @ ",
" "
]

delete_Icon = [
"24 24 3 1",
" c None",
". c #A40000",
"+ c #EE2A2A",
" ",
" ",
" . . ",
" .+. .+. ",
" .+++. .+++. ",
" .+++++. .+++++. ",
" .+++++++. .+++++++. ",
" .+++++++.+++++++. ",
" .+++++++++++++. ",
" .+++++++++++. ",
" .+++++++++. ",
" .+++++++. ",
" .+++++++++. ",
" .+++++++++++. ",
" .+++++++++++++. ",
" .+++++++.+++++++. ",
" .+++++++. .+++++++. ",
" .+++++. .+++++. ",
" .+++. .+++. ",
" .+. .+. ",
" . . ",
" ",
" ",
" "
]

memo_Allume_Icon = [
"24 24 9 1",
" c None",
". c #4F514E",
"+ c #635D41",
"@ c #676966",
"# c #848784",
"$ c #888A87",
"% c #E9D312",
"& c #FEEE4D",
"* c #FDFFFC",
" ",
" ",
" ",
" ",
" %%%%%% ",
" %%&&&&%% ",
" %%&&&&&&%% ",
" %%&&&**&&&%% ",
" %%&&&****&&&%% ",
" %&&&******&&&% ",
" %&&&******&&&% ",
" %&&&******&&&% ",
" %%&&&****&&&%% ",
" %%&&&**&&&%% ",
" %%&&&&&&%% ",
" %%%&&%%% ",
" .%%%%+ ",
" @..... ",
" ..#$$@ ",
" @@.... ",
" ..$$$@ ",
" @@.... ",
" $$$$ ",
" "
]

memo_Eteint_Icon = [
"24 24 9 1",
" c None",
". c #000000",
"+ c #204A87",
"@ c #555753",
"# c #4F514E",
"$ c #635D41",
"% c #676966",
"& c #848784",
"* c #888A87",
" ",
" ",
" ",
" ",
" ...... ",
" ........ ",
" .......... ",
" ............ ",
" ....+.+.+.+... ",
" ...+.+.+.++... ",
" ...@......@... ",
" ...@......@... ",
" ....@....@.... ",
" ....@..@.... ",
" ...@..@... ",
" ..@..@.. ",
" #@..@$ ",
" %##### ",
" ##&**% ",
" %%#### ",
" ##***% ",
" %%#### ",
" **** ",
" "
]

origin_Icon = [
"24 24 14 1",
" c None",
". c #EF2929",
"+ c #A40000",
"@ c #DDDFDC",
"# c #888A85",
"$ c #DDDEDB",
"% c #DCDEDB",
"& c #DCDEDC",
"* c #DBDDDA",
"= c #BABDB6",
"- c #555753",
"; c #729FCF",
"> c #3465A4",
", c #8191AA",
" ",
" ",
" .+ ",
" ..++ ",
" ....++ ",
" .....+++ ",
" ....@#++++ ",
" ....@@@#++++ ",
" ....@@@@@#++++ ",
" ....@@@@$@@#++++ ",
" ....@@@$@@%@@#++++ ",
" ....@@@@@@@@%@@#++++ ",
" ...@@@%%%%&%%*@@#+++ ",
" ..@@@@@@@@@@@@@@@#++ ",
" #@@=#---@@=====@# ",
" #@@=#---@@;>>>;@# ",
" #@@,#---@@;>>>;@# ",
" #@@,#---@@;>>>;@# ",
" #@@=#---@@-----@# ",
" #@@=#---@@@@@@@@# ",
" #@@=##--@@@@@@@@# ",
" ################# ",
" ",
" "
]

zero_Icon = [
"24 24 6 1",
" c None",
". c #CC0000",
"+ c #000000",
"@ c #BABDB6",
"# c #4E9A06",
"$ c #204A87",
" .. ",
" .. ",
" .. ",
" .. ",
" .. ",
" .. ",
" .. ",
" ++@ ..@ ++@ ",
" ++++@ +..+@ ++++@ ",
" ++@ ++@ ++..++@ ++@ ++@",
" +@ +@ +@.. +@ +@ +@",
"######+@###$$#+@######+@",
"######+@###$$#+@######+@",
" ++@ ++@ ++..++@ ++@ ++@",
" ++++ + ++++ + ++++ ",
" ++ ++ ++ ++ ++ ",
" + .. + ",
" ++ ..++ ",
" ++ ..+ ",
" .. ",
" .. ",
" .. ",
" .. ",
" .. "
]

reset_Icon = [
"24 24 3 1",
" c None",
". c #3465A4",
"+ c #888A85",
" ",
" ........ ",
" .++++++++. ",
" .++..+....+. ..... ",
" .+.. .+....+. .+++. ",
" .+. .+....+..+.+. ",
" ... .+....+.+.+. ",
" .+....+..+. ",
" .+......+. ",
" .+.....+. ",
" .+....+. ",
" ...... .+...+. ",
" .++++. .++++. ",
" .+...+. ...... ",
" .+....+. ",
" .+.....+. ",
" .+......+. ",
" .+..+....+. ",
" .+.+.+....+. ... ",
" .+.+..+....+. .+. ",
" .+++. .+....+. ..+. ",
" ..... .+....+..++. ",
" .++++++++. ",
" ........ "
]

code_Python_Icon = [
"24 24 3 1",
" c None",
". c #3B7AAC",
"+ c #EDD400",
" ",
" ++++++++++++++++++++. ",
" + . ",
" + . ",
" + ..... . ",
" + . ..... . ",
" + ....... + . ",
" + ... +++ . ",
" + ........ ++++ . ",
" + ......... +++++ . ",
" + ......... ++++++ . ",
" + ....... +++++++ . ",
" + ...... +++++++++ . ",
" + ..... +++++++++ . ",
" + .... ++++++++ . ",
" + ... +++ . ",
" + . +++++++ . ",
" + +++++ + . ",
" + +++++ . ",
" + . ",
" + . ",
" + . ",
" +.................... ",
" "
]

code_FC_Icon = [
"24 24 5 1",
" c None",
". c #000000",
"+ c #CB0208",
"@ c #204A86",
"# c #BABDB6",
" ",
" ",
" ",
" ",
" ",
"@@@ @@@ @@@ @@@",
"@ @ @ @",
"@ ++# @ @ ++# @",
"@ ++++# @ @ ++++# @",
"@ ++# ++#@ @ ++# ++#@",
"@ +# +#@ @ +# +#@",
"@ +# +#@ @ +# +#@",
"@ +# +#@ @ +# +#@",
"@ ++# ++#@ @ ++# ++#@",
"@ ++++ @ @ ++++ @",
"@ ++ @ @ ++ @",
"@ @ @ @",
"@ @ @ @",
"@@@ @@@ . @@@ @@@",
" .. ",
" . ",
" .. ",
" .. ",
" "
]

rotate_Icon = [
"24 24 4 1",
" c None",
". c #000100",
"+ c #000201",
"@ c #6695BF",
" ",
" ++++++++ ",
" +@@@@@@@@+ ",
" +@@......@@++ ",
" +@@.@@@@@@.@@@+ ++ ",
" +@@.@@++++@@.@@@+@+ ",
" +@@.@@+ +@@.@@@@+ ",
" +@@.@@+ +@@.@@@+ ",
" +@.@@+ +@@.@@@+ ",
" +@.@+ ++@@@@@@@+ ",
" +@.@+ ++@@@@@@+ ",
" +@.@+ +++@@@+ ",
" +@.@+ +++++ ",
" +@.@+ ",
" +@.@@+ ",
" +@@.@@+ +++ ",
" +@@.@@+ +@+ ",
" +@@.@@+++++@@+ ",
" +@@.@@@@@@@@+ ",
" +@@.....@@+ ",
" +@@@@@@@++ ",
" +++++++ ",
" ",
" "
]

translate_Icon = [
"24 24 9 1",
" c None",
". c #000100",
"+ c #000407",
"@ c #6694BF",
"# c #6D92BE",
"$ c #6A93C5",
"% c #6795C0",
"& c #6F93C0",
"* c #6896C1",
" ",
" ",
" .. ",
" .@. ",
" .@@.. ",
" .@@@@. ",
" .@@@@@. ",
" ..........@@@@@@. ",
" +**&%%&@&@@@@@@@. ",
" .............+@@@$.. ",
" +@@@@@@@@@@@@@@@@@@. ",
" ..........+@@@@@@@@@@. ",
" +@@@@@@@@@@@@@@@@@@+ ",
" ........+@@@@@@@@@++ ",
" +@@@@@@@@@@@@@@@. ",
" ..........@@@@@@. ",
" .@@@@@. ",
" .@@@@. ",
" .@@.. ",
" .@. ",
" .. ",
" ",
" ",
" "
]

OnClickApply_Icon = [
"24 24 9 1",
" c None",
". c #910000",
"+ c #F20001",
"@ c #54595E",
"# c #4B9A00",
"$ c #8A8C89",
"% c #B0B2AE",
"& c #FED758",
"* c #DFE1DC",
" ",
" .. ",
" ....... ",
" ....++ ",
" .+.+++ ",
" ....+++++ ",
" $.+++++++%%%% ",
" **$.++++++***&& ",
" %***$.+++++&*&&& ",
" *****$.++++&&&&* ",
" %******$.+++&&&**% ",
" *******&$.++&&&&** ",
" ***&&&&&&$.+&&&&&&& ",
" %*******&&&$.&&&&**% ",
" *********&&&$&&&**** ",
" ********&&&&&&&&&***% ",
" %*******&&&*&&&*&&&**% ",
" %%%%%%%%&&%%%&%%%&&%%$ ",
" %%%$%%%%%%%%%&%@%#%+%$ ",
" %%%$$%%%%%%%%&%%%%%%%$ ",
" %%%%%%%%%%%%%&%%%%%%%$ ",
" $%%%%%%%%%%%%%%%%%%%%$ ",
" @@@@@@@@@@@@@@@@@@@@@ ",
" "
]

normalWork_Icon = [
"24 24 9 1",
" c None",
". c #565854",
"+ c #555753",
"@ c #2E3436",
"# c #FFFFFF",
"$ c #FCE94F",
"% c #FEFEFE",
"& c #EDD400",
"* c #BABDB6",
" ",
" ...................... ",
" . . ",
" . +++++ +++++ . ",
" . . ",
" . . ",
" . +++++ +++++ . ",
" . . ",
" . . ",
" . +++++ +++++ . ",
" . . ",
" . . ",
" ...................... ",
" ",
" ",
" @@@@@@@@@@@@@@@",
" @#$$#########%@",
" @#&&###@@@#@@%@",
" @%&&%########%@",
" @#**#########%@",
" @@@@@@@@@@@@@@@",
" ",
" ",
" "
]

try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
class Ui_MainWindow(object):
def __init__(self ):
global path, path2
self.window = MainWindow
self.path = path

self.vueActive = FreeCADGui.ActiveDocument.ActiveView
self.click = self.vueActive.addEventCallback("SoMouseButtonEvent",self.souris)

def souris(self,info):
global sourisPass
if (info["Button"] == "BUTTON1") and (info["State"] == "DOWN"):
#time.sleep(0.02)
sourisPass = 0
#print("ok")

def setupUi(self, MainWindow):
self.window = MainWindow
MainWindow.setObjectName(_fromUtf8("MainWindow"))
global saveListView
# MainWindow.resize(360, 300)
# MainWindow.setMinimumSize(QtCore.QSize(330, 10))
# MainWindow.setMaximumSize(QtCore.QSize(330, 330))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))

####
self.groupBox_Rotation = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_Rotation.setEnabled(False)

self.RB_Bond_Box_Center = QtWidgets.QRadioButton()
self.RB_Bond_Box_Center.setChecked(True)
self.RB_Bond_Box_Center.setIcon(QtGui.QIcon(QtGui.QPixmap(boundBox_Center_Icon))) #icone dans une variable
self.RB_Bond_Box_Center.clicked.connect(self.on_RB_CenterRot)

self.RB_Center_Mass = QtWidgets.QRadioButton()
self.RB_Center_Mass.setIcon(QtGui.QIcon(QtGui.QPixmap(centerMass_Icon))) # icone dans une variable
self.RB_Center_Mass.clicked.connect(self.on_RB_CenterRot)

self.RB_Point_Clicked = QtWidgets.QRadioButton()
self.RB_Point_Clicked.setIcon(QtGui.QIcon(QtGui.QPixmap(point_Clicked_Icon))) # icone dans une variable
self.RB_Point_Clicked.clicked.connect(self.on_RB_CenterRot)

####
self.groupBox_Axis = QtWidgets.QGroupBox()
self.groupBox_Axis.setEnabled(False)

self.RB_Rotation_0 = QtWidgets.QRadioButton() # factice pour bouton invisible
self.RB_Rotation_0.setVisible(False)
# self.RB_Rotation_0.clicked.connect(self.on_RB_Rotation_0)

self.RB_Rotation_X = QtWidgets.QRadioButton()
self.RB_Rotation_X.setChecked(True)
self.RB_Rotation_X.setIcon(QtGui.QIcon(QtGui.QPixmap(axis_Z_Icon))) # icone dans une variable
self.RB_Rotation_X.clicked.connect(self.on_RB_Rotation_X)

self.RB_Rotation_Y = QtWidgets.QRadioButton()
self.RB_Rotation_Y.setIcon(QtGui.QIcon(QtGui.QPixmap(axis_Y_Icon))) # icone dans une variable
self.RB_Rotation_Y.clicked.connect(self.on_RB_Rotation_Y)
# self.RB_Angle_Y.setFont(QtGui.QFont(self.FontImpost,weight=QtGui.QFont.Bold)) # Bold
# self.RB_Angle_Y.setStyleSheet("color : #008700") # Color text

self.RB_Rotation_Z = QtWidgets.QRadioButton()
self.RB_Rotation_Z.setIcon(QtGui.QIcon(QtGui.QPixmap(axis_X_Icon))) # icone dans une variable
self.RB_Rotation_Z.clicked.connect(self.on_RB_Rotation_Z)

self.RB_Direction_D = QtWidgets.QRadioButton()
self.RB_Direction_D.setIcon(QtGui.QIcon(QtGui.QPixmap(direction_Icon))) # icone dans une variable
self.RB_Direction_D.clicked.connect(self.on_RB_Direction_D)
####

self.groupBox_Pos_Mouse = QtWidgets.QGroupBox()
self.groupBox_Pos_Mouse.setEnabled(False)

self.DS_Pos_Mouse_X = QtWidgets.QDoubleSpinBox()
self.DS_Pos_Mouse_X.setMinimum(-999999.9)
self.DS_Pos_Mouse_X.setMaximum(99999999.9)
self.DS_Pos_Mouse_X.setDecimals(6)
self.DS_Pos_Mouse_X.setSuffix(" X")
# self.DS_Pos_Mouse_X.setIcon(QtGui.QIcon(QtGui.QPixmap(CameraToFace))) # icone dans une variable
self.DS_Pos_Mouse_X.valueChanged.connect(self.on_DS_Pos_Mouse_X)

self.DS_Pos_Mouse_Y = QtWidgets.QDoubleSpinBox()
self.DS_Pos_Mouse_Y.setMinimum(-999999.9)
self.DS_Pos_Mouse_Y.setMaximum(99999999.9)
self.DS_Pos_Mouse_Y.setDecimals(6)
self.DS_Pos_Mouse_Y.setSuffix(" Y")
# self.PB_To_Face.setIcon(QtGui.QIcon(QtGui.QPixmap(CameraToFace))) # icone dans une variable
self.DS_Pos_Mouse_Y.valueChanged.connect(self.on_DS_Pos_Mouse_Y)

self.DS_Pos_Mouse_Z = QtWidgets.QDoubleSpinBox()
self.DS_Pos_Mouse_Z.setMinimum(-999999.9)
self.DS_Pos_Mouse_Z.setMaximum(99999999.9)
self.DS_Pos_Mouse_Z.setDecimals(6)
self.DS_Pos_Mouse_Z.setSuffix(" Z")
# self.PB_To_Face.setIcon(QtGui.QIcon(QtGui.QPixmap(CameraToFace))) # icone dans une variable
self.DS_Pos_Mouse_Z.valueChanged.connect(self.on_DS_Pos_Mouse_Z)

####
self.groupBox_Work = QtWidgets.QGroupBox()
self.groupBox_Work.setEnabled(False)

# self.SC_Slider_Bar = QtWidgets.QSlider()
# self.SC_Slider_Bar.setMinimum(0.0)
# self.SC_Slider_Bar.setMaximum(359.0)
# self.SC_Slider_Bar.setValue(0.0)
# self.SC_Slider_Bar.setSliderPosition(0)
# self.SC_Slider_Bar.setOrientation(QtCore.Qt.Horizontal)
# self.SC_Slider_Bar.valueChanged.connect(self.on_SC_Slider_Bar)

self.LE_Increment = QtWidgets.QLineEdit()
self.LE_Increment.setReadOnly(True)
self.LE_Increment.setText(str(0.0))
#self.LE_Increment.returnPressed.connect(self.on_LE_Increment_Pressed)
self.LE_Increment.textChanged.connect(self.on_LE_Increment_Pressed)

self.DS_Scroll_Bar = QtWidgets.QDoubleSpinBox()
self.DS_Scroll_Bar.setMinimum(-360.0)
self.DS_Scroll_Bar.setMaximum(360.0)
self.DS_Scroll_Bar.setSuffix(" Degrees")
self.DS_Scroll_Bar.setDecimals(4)
self.DS_Scroll_Bar.valueChanged.connect(self.on_DS_Scroll_Bar)

self.PB_Apply = QtWidgets.QPushButton()
self.PB_Apply.setAutoRepeat(True)
self.PB_Apply.setIcon(QtGui.QIcon(QtGui.QPixmap(apply_Icon))) # icone dans une variable
self.PB_Apply.clicked.connect(self.on_PB_Apply_clicked)

self.CB_Position = QtWidgets.QCheckBox()
#self.CB_Position.setEnabled(False)
self.CB_Position.setIcon(QtGui.QIcon(QtGui.QPixmap(translate_Icon))) #icone dans une variable
self.CB_Position.clicked.connect(self.on_CB_Position)

# self.CB_Point = QtWidgets.QCheckBox()
# self.CB_Point.setEnabled(False)
# self.CB_Point.clicked.connect(self.on_CB_Point)
self.PB_Point = QtWidgets.QPushButton()
#self.PB_Point.setEnabled(False)
self.PB_Point.setIcon(QtGui.QIcon(QtGui.QPixmap(point_Icon))) # icone dans une variable
self.PB_Point.clicked.connect(self.on_CB_Point)

# self.CB_Free = QtWidgets.QCheckBox()
# self.CB_Free.setEnabled(False)
## self.CB_Free.clicked.connect(self.on_CB_Free)

self.groupBox_Data = QtWidgets.QGroupBox()
self.groupBox_Data.setEnabled(False)

self.TE_Memorize = QtWidgets.QListView()
saveListView = QtGui.QStandardItemModel()
self.TE_Memorize.setModel(saveListView)
self.TE_Memorize.setSelectionRectVisible(True)#
self.TE_Memorize.setAlternatingRowColors(True)#
self.TE_Memorize.setStyleSheet("alternate-background-color:#fdeeee;")
self.TE_Memorize.clicked[QtCore.QModelIndex].connect(self.on_TE_Clicked)

self.PB_Save_Memorize = QtWidgets.QPushButton()
self.PB_Save_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(save_Icon))) # icone dans une variable
self.PB_Save_Memorize.clicked.connect(self.on_PB_Save_Memorize)

self.PB_ClearMemo = QtWidgets.QPushButton()
self.PB_ClearMemo.setIcon(QtGui.QIcon(QtGui.QPixmap(clear_Icon))) # icone dans une variable
self.PB_ClearMemo.clicked.connect(self.on_PB_ClearMemo)

self.PB_Delete_Line_Memory = QtWidgets.QPushButton()
self.PB_Delete_Line_Memory.setIcon(QtGui.QIcon(QtGui.QPixmap(delete_Icon))) # icone dans une variable
self.PB_Delete_Line_Memory.clicked.connect(self.on_PB_Delete_Line_Memory)

self.PB_Memorize = QtWidgets.QPushButton()
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Eteint_Icon))) # icone dans une variable
self.PB_Memorize.clicked.connect(self.on_PB_Memorize)

self.CB_On_Click_Apply = QtWidgets.QCheckBox()
self.CB_On_Click_Apply.setIcon(QtGui.QIcon(QtGui.QPixmap(OnClickApply_Icon))) # icone dans une variable
self.CB_On_Click_Apply.clicked.connect(self.on_CB_On_Click_Apply)

self.CB_DataInMacro = QtWidgets.QCheckBox()
self.CB_DataInMacro.setIcon(QtGui.QIcon(QtGui.QPixmap(code_Python_Icon))) # icone dans une variable
self.CB_DataInMacro.clicked.connect(self.On_CB_DataInMacro)

self.label_00 = QtWidgets.QLabel()
self.label_00.setStyleSheet("color : #ffffff; background-color: red; font: bold 10px;") # white red bold
#self.label_00.setToolTip("Display the modification Axis and Rotation or Position")
####

self.groupBox_Command = QtWidgets.QGroupBox()

self.PB_Quit = QtWidgets.QPushButton()
self.PB_Quit.setIcon(QtGui.QIcon(QtGui.QPixmap(quit_Icon))) # icone dans une variable
self.PB_Quit.clicked.connect(self.on_PB_Quit_clicked)

self.PB_Original = QtWidgets.QPushButton()
self.PB_Original.setIcon(QtGui.QIcon(QtGui.QPixmap(origin_Icon))) # icone dans une variable
self.PB_Original.clicked.connect(self.on_PB_Original_clicked)

self.PB_Zero = QtWidgets.QPushButton()
self.PB_Zero.setIcon(QtGui.QIcon(QtGui.QPixmap(zero_Icon))) # icone dans une variable
self.PB_Zero.clicked.connect(self.on_PB_Zero_clicked)

self.PB_Reset = QtWidgets.QPushButton()
self.PB_Reset.setIcon(QtGui.QIcon(QtGui.QPixmap(reset_Icon))) # icone dans une variable
self.PB_Reset.clicked.connect(self.on_PB_Reset_clicked)

#### Gridlayout Header
self.gridLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.gridLayout_00_00 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_00_00.setContentsMargins(10, 10, 10, 10)#Gauche Haut Droit Bas
#### Gridlayout Header
#### Gridlayout BEGIN
self.grid_00_01 = QtWidgets.QGridLayout()
# self.gridLayoutWidget_3 = QtWidgets.QWidget(self.groupBox_Rotation)
self.grid_00_01.addWidget(self.groupBox_Rotation, 0, 0, 1, 1)
self.grid_00_01.setContentsMargins(0, 0, 0, 0) #Gauche Haut Droite Bas
self.grid_00_01_00 = QtWidgets.QGridLayout(self.groupBox_Rotation)
self.grid_00_01_00.setContentsMargins(10, 10, 0, 10)
self.grid_00_01_00.addWidget(self.RB_Bond_Box_Center, 0, 0, 1, 1)
self.grid_00_01_00.addWidget(self.RB_Center_Mass, 1, 0, 1, 1)
self.grid_00_01_00.addWidget(self.RB_Point_Clicked, 2, 0, 1, 1)
self.gridLayout_00_00.addLayout(self.grid_00_01, 0, 0, 1, 1)
####
self.grid_00_02 = QtWidgets.QGridLayout()
self.grid_00_02.addWidget(self.groupBox_Axis, 0, 0, 1, 1)
self.grid_00_02.setContentsMargins(0, 0, 0, 0)
self.grid_00_02_00 = QtWidgets.QGridLayout(self.groupBox_Axis)
self.grid_00_02_00.setContentsMargins(10, 10, 0, 10)
self.grid_00_02_00.addWidget(self.RB_Rotation_X, 0, 0, 1, 1)
self.grid_00_02_00.addWidget(self.RB_Rotation_Y, 1, 0, 1, 1)
self.grid_00_02_00.addWidget(self.RB_Rotation_Z, 2, 0, 1, 1)
self.grid_00_02_00.addWidget(self.RB_Direction_D, 3, 0, 1, 1)
self.gridLayout_00_00.addLayout(self.grid_00_02, 0, 1, 1, 1)
####
self.grid_00_03 = QtWidgets.QGridLayout()
self.grid_00_03.addWidget(self.groupBox_Pos_Mouse, 1, 0, 1, 1)
self.grid_00_03.setContentsMargins(0, 0, 0, 0)
self.grid_00_03_00 = QtWidgets.QGridLayout(self.groupBox_Pos_Mouse)
self.grid_00_03_00.setContentsMargins(10, 10, 10, 10)
self.grid_00_03_00.addWidget(self.DS_Pos_Mouse_X, 0, 0, 1, 1)
self.grid_00_03_00.addWidget(self.DS_Pos_Mouse_Y, 0, 1, 1, 1)
self.grid_00_03_00.addWidget(self.DS_Pos_Mouse_Z, 0, 2, 1, 1)
self.gridLayout_00_00.addLayout(self.grid_00_03, 1, 0, 1, 2)
####
self.grid_00_044 = QtWidgets.QGridLayout()
self.grid_00_044.addWidget(self.groupBox_Work, 2, 0, 1, 1)
self.grid_00_044.setContentsMargins(0, 0, 0, 0)
self.grid_00_044_00 = QtWidgets.QGridLayout(self.groupBox_Work)
self.grid_00_044_00.addWidget(self.CB_Position, 0, 0, 1, 1)
self.grid_00_044_00.addWidget(self.PB_Point, 0, 1, 1, 1)
# self.grid_00_044_00.addWidget(self.CB_Free, 0, 2, 1, 1)
self.grid_00_044_00.addWidget(self.LE_Increment, 1, 0, 1, 1)
self.grid_00_044_00.addWidget(self.DS_Scroll_Bar, 1, 1, 1, 1)
self.grid_00_044_00.addWidget(self.PB_Apply, 1, 2, 1, 1)
self.grid_00_044_00.addWidget(self.label_00, 2, 0, 1, 3)
# self.grid_00_044_00.addWidget(self.SC_Slider_Bar, 2, 0, 1, 3)
self.gridLayout_00_00.addLayout(self.grid_00_044, 2, 0, 1, 2)
####
self.grid_00_044b = QtWidgets.QGridLayout()
self.grid_00_044b.addWidget(self.groupBox_Data, 3, 0, 1, 1)
self.grid_00_044b.setContentsMargins(0, 0, 0, 0)
self.grid_00_044b_00 = QtWidgets.QGridLayout(self.groupBox_Data)
self.grid_00_044b_00.addWidget(self.TE_Memorize, 0, 0, 1, 4)
self.grid_00_044b_00.addWidget(self.PB_Save_Memorize, 1, 0, 1, 1)
self.grid_00_044b_00.addWidget(self.PB_ClearMemo, 1, 1, 1, 1)
self.grid_00_044b_00.addWidget(self.PB_Delete_Line_Memory, 1, 2, 1, 1)
self.grid_00_044b_00.addWidget(self.PB_Memorize, 1, 3, 1, 1)
self.grid_00_044b_00.addWidget(self.CB_DataInMacro, 2, 0, 1, 1)
self.grid_00_044b_00.addWidget(self.CB_On_Click_Apply, 2, 1, 1, 1)
self.gridLayout_00_00.addLayout(self.grid_00_044b, 3, 0, 1, 2)
####
self.grid_00_08 = QtWidgets.QGridLayout()
self.grid_00_08.addWidget(self.groupBox_Command, 4, 0, 1, 1)
self.grid_00_08.setContentsMargins(0, 0, 0, 0)
self.grid_00_08_00 = QtWidgets.QGridLayout(self.groupBox_Command)
self.grid_00_08_00.addWidget(self.PB_Quit, 0, 0, 1, 1)
self.grid_00_08_00.addWidget(self.PB_Original, 0, 1, 1, 1)
self.grid_00_08_00.addWidget(self.PB_Zero, 0, 2, 1, 1)
self.grid_00_08_00.addWidget(self.PB_Reset, 0, 3, 1, 1)
self.gridLayout_00_00.addLayout(self.grid_00_08, 4, 0, 1, 2)
#### Gridlayout END

MainWindow.setCentralWidget(self.centralwidget)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
global path

MainWindow.setWindowFlags(PySide2.QtCore.Qt.WindowStaysOnTopHint) # this function turns the front window (stay to hint)
MainWindow.setWindowIcon(QtGui.QIcon(self.path+"Macro_Rotate_To_Point.png")) # change l'icone de la fenetre principale
MainWindow.setWindowTitle(__title__ + " (" + __version__ + " : " + __date__ + " (rmu)")

_translate = QtCore.QCoreApplication.translate
self.groupBox_Rotation.setTitle(_translate("MainWindow", "Point Rotation"))
self.RB_Bond_Box_Center.setText(_translate("MainWindow", "Bounbox Center"))
self.RB_Bond_Box_Center.setToolTip(_translate("MainWindow", "Point rotation on BoundBox Center"))
self.RB_Center_Mass.setText(_translate("MainWindow", "Center of Mass"))
self.RB_Center_Mass.setToolTip(_translate("MainWindow", "Point rotation on Center Mass"))
self.RB_Point_Clicked.setText(_translate("MainWindow", "Point clicked"))
self.RB_Point_Clicked.setToolTip(_translate("MainWindow", "Point rotation on Point Mouse clicked on the object"+"\n"
"If twoo points are clicked, the second point is used for axis rotation"+"\n"
"The point axis rotation Can be changed during the work as long as the object is selected"+"\n"
"For this press the CTRL KEY and click the new point rotation"))
####
self.groupBox_Axis.setTitle(_translate("MainWindow", "Axis Rotation"))
self.RB_Rotation_X.setText(_translate("MainWindow", "Rotation(Z) Yaw"))
self.RB_Rotation_X.setToolTip(_translate("MainWindow", "Rotation on Axis Yaw (Z)"))
self.RB_Rotation_Y.setText(_translate("MainWindow", "Rotation(Y) Pitch"))
self.RB_Rotation_Y.setToolTip(_translate("MainWindow", "Rotation on Axis Pitch (Y)"))
self.RB_Rotation_Z.setText(_translate("MainWindow", "Rotation(X) Roll"))
self.RB_Rotation_Z.setToolTip(_translate("MainWindow", "Rotation on Axis Roll (X)"))
self.RB_Direction_D.setText(_translate("MainWindow", "Direction"))
self.RB_Direction_D.setToolTip(_translate("MainWindow", "Rotation or Translation on Direction" + "\n"
"For use the Direction option:" + "\n"
"Select First: the object to Rotate/Translate" + "\n"
"Second: the path: Line, Wire or Edge"))
####
self.groupBox_Work.setTitle(_translate("MainWindow", "Work"))
self.groupBox_Pos_Mouse.setTitle(_translate("MainWindow", "Coordinates Point clicked"))
self.groupBox_Pos_Mouse.setToolTip(_translate("MainWindow", "Position click mouse modification possible only with mode Point clicked"))
self.DS_Pos_Mouse_X.setToolTip(_translate("MainWindow", "Position click mouse X" + "\n" +
"modification only with mode Point clicked"))
self.DS_Pos_Mouse_Y.setToolTip(_translate("MainWindow", "Position click mouse Y" + "\n" +
"modification only with mode Point clicked"))
self.DS_Pos_Mouse_Z.setToolTip(_translate("MainWindow", "Position click mouse Z" + "\n" +
"modification only with mode Point clicked"))
self.CB_Position.setText(_translate("MainWindow", "Translation"))
self.CB_Position.setToolTip(_translate("MainWindow", "Check for move the object to axis choice X, Y or Z"))
#self.CB_Point.setText(_translate("MainWindow", "Point"))
#self.CB_Point.setToolTip(_translate("MainWindow", "If checked, create one point to visualise the point rotation"))
self.PB_Point.setText(_translate("MainWindow", "Point"))
self.PB_Point.setToolTip(_translate("MainWindow", "Create one point to visualise the point rotation"))
#self.CB_Free.setText(_translate("MainWindow", "Free"))
#self.CB_Free.setToolTip(_translate("MainWindow", "This checkBox switch the Application button"))
self.LE_Increment.setToolTip(_translate("MainWindow", "Display the original Data + the modification"))
self.DS_Scroll_Bar.setToolTip(_translate("MainWindow", "Enter the modification"))
self.PB_Apply.setToolTip(_translate("MainWindow", "Apply the modification"))
self.PB_Apply.setText(_translate("MainWindow", "Apply"))
self.label_00.setText(_translate("MainWindow", " Select one Object or give one value Angle/Dimension"))
####
self.groupBox_Data.setTitle(_translate("MainWindow", "Data"))
self.PB_Save_Memorize.setText(_translate("MainWindow", "Save"))
self.PB_Save_Memorize.setToolTip(_translate("MainWindow", "Save the memorized placement" + "\n"
"Format to save : [Placement.Base], [Placement.Rotation.toEuler]" + "\n"
"Ex: [0.0,0.0,0.0],[0.0,0.0,0.0] with the ext: .CoorInfo" + "\n"
"If the file exist, the data is saved in Append (adding) mode" + "\n"
"If the CheckBox is checked for a Macro the file is saved in Write mode"))
self.PB_ClearMemo.setText(_translate("MainWindow", "Clear"))
self.PB_ClearMemo.setToolTip(_translate("MainWindow", "Clear the memo data" + "\n"
"The Reset button is not actif for this option"))
self.PB_Delete_Line_Memory.setText(_translate("MainWindow", "Delete"))
self.PB_Delete_Line_Memory.setToolTip(_translate("MainWindow", "Delete the line selected"))
self.PB_Memorize.setText(_translate("MainWindow", "Memorize"))
self.PB_Memorize.setToolTip(_translate("MainWindow", "Memorize the placement displayed"))
self.CB_DataInMacro.setText(_translate("MainWindow", "Macro"))
self.CB_DataInMacro.setToolTip(_translate("MainWindow", "If checked, the coordinate is saved in Python code (complete macro) in your Macro directory" + "\n"
"Actual : " + path + "\n"
"Select the object and run the macro" + "\n"
"\t" + "The macro saved has various options :" + "\n"
"\t" + " (Q)uit, (D)ecrease, (I)ncrease, (P)ause, (S)tep, (M)emo" + "\n"
"If this is not checked, the data hare saved in coordinate mode" + "\n"
"\t" + "Ex: [0.0,0.0,0.0],[0.0,0.0,0.0] with the ext: .CoorInfo" + "\n"))
self.CB_On_Click_Apply.setText(_translate("MainWindow", "Memo on click"))
self.CB_On_Click_Apply.setToolTip(_translate("MainWindow", "Memorize the coordinates on all Click Apply button"))
####
self.groupBox_Command.setTitle(_translate("MainWindow", "Command"))
self.PB_Quit.setText(_translate("MainWindow", "Quit"))
self.PB_Quit.setToolTip(_translate("MainWindow", "Quite the macro"))
self.PB_Original.setText(_translate("MainWindow", "Original"))
self.PB_Original.setToolTip(_translate("MainWindow", "Move the object to the original position"))
self.PB_Reset.setText(_translate("MainWindow", "Reset"))
self.PB_Reset.setToolTip(_translate("MainWindow", "Reset the complete data macro"))
self.PB_Zero.setText(_translate("MainWindow", "0,0,0"))
self.PB_Zero.setToolTip(_translate("MainWindow", "Move the object to the base coordinates 0, 0, 0"))


def on_DS_Pos_Mouse_X(self,val):
global positionMouse
global axisX

positionMouse = [val, positionMouse[1], positionMouse[2]]
axisX = positionMouse[0]
self.DS_Pos_Mouse_X.setValue(axisX)
# print("on_DS_Pos_Mouse_X ", val)

def on_DS_Pos_Mouse_Y(self,val):
global positionMouse
global axisY

positionMouse = [positionMouse[0], val, positionMouse[2]]
axisY = positionMouse[1]
self.DS_Pos_Mouse_Y.setValue(axisY)
# print("on_DS_Pos_Mouse_Y ", val)

def on_DS_Pos_Mouse_Z(self,val):
global positionMouse
global axisZ

positionMouse = [positionMouse[0], positionMouse[1], val]
axisZ = positionMouse[2]
self.DS_Pos_Mouse_Z.setValue(axisZ)
# print("on_DS_Pos_Mouse_Z ", val)

# def on_SC_Slider_Bar(self,val):
# global ui
# global valeur
# global myObject
#
# if (myObject != "") and (self.CB_Free.isChecked()):
# valeur = val
# self.DS_Scroll_Bar.setValue(1)
# self.SC_Slider_Bar.setValue(valeur)
# ui.on_PB_Apply_clicked()
#
## if self.CB_Free.isChecked():
## ui.on_PB_Apply_clicked()
## else:
## self.DS_Scroll_Bar.setValue(0.0)
## self.SC_Slider_Bar.setValue(0.0)

# print("on_SC_Scroll_Bar ", valeur)

def on_PB_Delete_Line_Memory(self): #self.TE_Memorize #QListView
global countMemory
global saveOnDisk

self.model = model = QtGui.QStandardItemModel()
try:
self.PB_Delete_Line_Memory.setStyleSheet("Base")
lineSelected = self.TE_Memorize.selectionModel().selectedRows()[0].row()
#textLigne = self.TE_Memorize.selectionModel().currentIndex().data() # affiche la ligne selectionnee
self.TE_Memorize.model().removeRow(lineSelected)
del saveOnDisk[lineSelected]
countMemory -= 1
self.PB_Memorize.setText("Memo (" + str(countMemory) + ")")
except Exception:
self.PB_Delete_Line_Memory.setStyleSheet("background-color: rgb(255, 0, 0)")
# print("on_PB_Delete_Line_Memory ")

def on_TE_Clicked(self, index): # click dans la fenetre
global saveOnDisk
global saveListView
global memorySelected

####ori colore la ligne######
# item = saveListView.itemFromIndex(index)
# item.setBackground(QtGui.QBrush(QtGui.QColor("#ef1919")))
# if (item.index().row()) in memorySelected:
## memorySelected.remove(item.index().row())
# baseBackground = self.TE_Memorize.palette().color(QPalette.Window)
# item.setBackground(QtGui.QBrush(QtGui.QColor(baseBackground)))
# else:
# memorySelected.append(item.index().row())
## print(memorySelected)
####ori colore la ligne######

item = saveListView.itemFromIndex(index)
memorySelected = []
memorySelected.append(item.index().row())
# print("on_TE_Clicked ",memorySelected[0]) #self.TE_Memorize

def on_PB_Memorize(self):
global myObject
global saveOnDisk
global saveListView
global countMemory
global valeur

# if (valeur != 0):
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Allume_Icon))) # icone dans une variable
countMemory += 1
xPB = str(myObject.Placement.Base[0])
yPB = str(myObject.Placement.Base[1])
zPB = str(myObject.Placement.Base[2])
xPR = str(myObject.Placement.Rotation.toEuler()[0])
yPR = str(myObject.Placement.Rotation.toEuler()[1])
zPR = str(myObject.Placement.Rotation.toEuler()[2])
#[(3.7,0.0,41.8), (0.0,3.0,0.0)],
#Placement.Base Placement.Rotation.toEuler()
dummy = "[("+xPB+","+yPB+","+zPB+"),("+xPR+","+yPR+","+zPR+")],"
saveOnDisk.append(dummy)
self.PB_Memorize.setText("Memo (" + str(countMemory) + ")")
self.PB_Memorize.setStyleSheet("background-color: rgb(188, 245, 169)"); # bouton
self.PB_Delete_Line_Memory.setStyleSheet("Base")
item = QtGui.QStandardItem(dummy)
saveListView.appendRow(item)
# else:
# self.PB_Memorize.setStyleSheet("background-color: #ff0000;")
# self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Eteint_Icon))) # icone dans une variable
# print("on_PB_Memorize ",saveListView," ",str(countMemory))

def on_PB_Save_Memorize(self):
global pathFile
global saveOnDisk
global countMemory
global path

if countMemory != 0:
if self.CB_DataInMacro.isChecked():
# SaveName, Filter = PySide2.QtWidgets.QFileDialog.getSaveFileName(None, "Save a file FCMacro", path, "FCMacro (*.FCMacro);;Python (*.py)") # PySide2
nomMacro = FreeCAD.ActiveDocument.Name
SaveName, Filter = PySide2.QtWidgets.QFileDialog.getSaveFileName(None, "Save a file FCMacro", path + nomMacro, "(*.FCMacro);;Python (*.py)") # PySide2
else:
SaveName, Filter = PySide2.QtWidgets.QFileDialog.getSaveFileName(None, "Save a file CoorInfo", pathFile, "CoorInfo (*.CoorInfo);;Ascii (*.asc);;TXT (*.txt)") # PySide2

if SaveName == "": # if the name file are not selected then Abord process
App.Console.PrintMessage("Process aborted"+"\n")
else: # if the name file are selected or created then
####new2
pathFile = os.path.dirname(SaveName) + "/" #= C:/Provisoire400/
formatFichier = os.path.splitext(SaveName)[1] #= .png
SaveName = os.path.splitext(SaveName)[0] #= /home/kubuntu/.FreeCAD/Macro/Texture_007_H #= C:/Provisoire400/image3D
SaveNameformatFichier = SaveName + formatFichier #= C:/Provisoire400/image3D.png
####new2
######## sauve le dernier chemin utilise si n'est pas une macro########
if self.CB_DataInMacro.isChecked():
None
else:
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetString("setLastPath",pathFile)
######## sauve le dernier chemin utilise si n'est pas une macro########

App.Console.PrintMessage("Registration of "+SaveNameformatFichier+"\n")
try:
if self.CB_DataInMacro.isChecked():
file = open(SaveNameformatFichier, 'w') #'w'write
else:
file = open(SaveNameformatFichier, 'a') #'a'append
try:
#### macro first section begin
if self.CB_DataInMacro.isChecked():
file.write("##" + "\n")
try:
file.write("##Created by : " + __title__ + " : " + __version__ + ":" + __date__ + " : " + __author__ + "\n")
file.write("##Document : " + FreeCAD.ActiveDocument.Name + "\n")
file.write("##Date : " + str(QDate.currentDate().toString()) + "\n")
file.write("##Object : " + str(FreeCADGui.Selection.getSelection()[0].Name) + "\n")
except Exception: None
file.write("import Draft, Part" + "\n")
file.write("import PySide2" + "\n")
file.write("from pivy import coin" + "\n")
file.write("import time, os" + "\n")
file.write("" + "\n")
file.write("import FreeCAD, FreeCADGui" + "\n")
file.write("App = FreeCAD" + "\n")
file.write("Gui = FreeCADGui" + "\n")
file.write("" + "\n")
file.write("global Document; Document = " + chr(34) + FreeCAD.ActiveDocument.Name + chr(34) + "\n")
file.write("global xxData ; xxData = [] " + "\n")
file.write("global xxKey ; xxKey = " + chr(34) + chr(34) + "\n")
file.write("global v, o, c" + "\n")
file.write("global vitesse ; vitesse = 0.02" + "\n")
file.write("" + "\n")
file.write("def help():" + "\n")
file.write(" global xxData" + "\n")
file.write(" global Document" + "\n")
file.write(' App.Console.PrintMessage("__' + FreeCAD.ActiveDocument.Name + '__"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("__" + str(len(xxData)) + " Coordinates__"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("Type Key Q to Quit"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("Type Key D to Decrease speed"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("Type Key I to Increase speed"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("Type Key P to Pause/Continue or key RETURN or ESCAPE"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("Type Key S to Step by Step (key RETURN or ESCAPE to continue)"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("Type Key M for this message"+"' + chr(92) + 'n")' + "\n")
file.write(' App.Console.PrintMessage("____________________________"+"' + chr(92) + 'n")' + "\n")
file.write('\n')
file.write('class ViewObserver:' + "\n")
file.write(' def logPosition(self, info):' + "\n")
file.write(' global xxKey' + "\n")
file.write(' global v, o, c' + "\n")
file.write(' global vitesse' + "\n")
file.write('' + "\n")
file.write(' xxKey = info["Key"].upper()' + "\n")
file.write(' if xxKey in "QIDPSM" or xxKey == "RETURN" or xxKey == "PAD_ENTER" or xxKey == "ESCAPE":' + "\n")
file.write(' if (xxKey == "Q"): # Quit' + "\n")
file.write(' v.removeEventCallback("SoKeyboardEvent",c)' + "\n")
file.write(' FreeCAD.Console.PrintMessage("End " + Document + "' + chr(92) + 'n")' + "\n")
file.write('' + "\n")
file.write(' if (xxKey == "I"): # Increase' + "\n")
file.write(' vitesse -= 0.01' + "\n")
file.write(' if vitesse <= 0:' + "\n")
file.write(' vitesse = 0' + "\n")
file.write(' App.Console.PrintMessage("Speed maximum"+"' + chr(92) + 'n")' + "\n")
file.write(' else:' + "\n")
file.write(' App.Console.PrintMessage(str(vitesse)+"' + chr(92) + 'n")' + "\n")
file.write('' + "\n")
file.write(' if (xxKey == "D"): # Decrease' + "\n")
file.write(' vitesse += 0.01' + "\n")
file.write(' App.Console.PrintMessage(str(vitesse)+"' + chr(92) + 'n")' + "\n")
file.write('' + "\n")
file.write(' if (xxKey == "M"): # Help memo' + "\n")
file.write(' help()' + "\n")
file.write('##Begin of file' + "\n")
file.write('xxData = [' + "\n")
#### save data
for i in saveOnDisk:
file.write(i + "\n")
#### save data
#### macro second section begin
if self.CB_DataInMacro.isChecked():
file.write(']' + "\n")
file.write('##End of file' + "\n")
file.write('' + "\n")
file.write('createPoint = 0 # 0=not point 1=create point #used by "S" :Step to Step' + "\n")
file.write('try:' + "\n")
file.write(' v = Gui.activeDocument().activeView()' + "\n")
file.write(' o = ViewObserver()' + "\n")
file.write(' c = v.addEventCallback("SoKeyboardEvent",o.logPosition)' + "\n")
file.write('' + "\n")
file.write(' ##Select the object' + "\n")
file.write(' myObject = FreeCADGui.Selection.getSelection()[0] #select the object' + "\n")
file.write(' help() #help message' + "\n")
file.write('' + "\n")
file.write(' ##Loop' + "\n")
file.write(' while xxKey != "Q":' + "\n")
file.write(' comptCoordinate = -1 # coordinte 0 to ...x' + "\n")
file.write(' for p in xxData:' + "\n")
file.write(' #if (xxKey == "Q"): break # Quit the loop after finish the complete loop (commented by default: if used quit the loop as is)' + "\n")
file.write(' comptCoordinate += 1' + "\n")
file.write(' ## p[0]=Coordinate x,y,z; p[1]=Rotation angle x (Roll), y (Pitch), z (Yaw)' + "\n")
file.write(' px = float(p[0][0]); rx = float(p[1][0])' + "\n")
file.write(' py = float(p[0][1]); ry = float(p[1][1])' + "\n")
file.write(' pz = float(p[0][2]); rz = float(p[1][2])' + "\n")
file.write(' myObject.Placement=App.Placement(App.Vector(px,py,pz), App.Rotation(rx,ry,rz), App.Vector(0,0,0))' + "\n")
file.write(' Gui.updateGui() # rafraichi l''ecran' + "\n")
file.write(' time.sleep(vitesse)' + "\n")
file.write('' + "\n")
file.write(' if xxKey == "P": # Pause' + "\n")
file.write(' xxKey = ""' + "\n")
file.write(' comptLoop = 0' + "\n")
file.write(' while xxKey != "P":' + "\n")
file.write(' if xxKey == "RETURN" or xxKey == "PAD_ENTER" or xxKey == "ESCAPE": break' + "\n")
file.write(' comptLoop += 1' + "\n")
file.write(' if comptLoop > 50000:' + "\n")
file.write(' comptLoop = 0' + "\n")
file.write(' App.Console.PrintError("You is in mode Pause : Type P or RETURN or ESCAPE to continue" + "' + chr(92) + 'n")' + "\n")
file.write(' Gui.updateGui() # rafraichi l''ecran' + "\n")
file.write(' xxKey = ""' + "\n")
file.write('' + "\n")
file.write(' if xxKey == "S": # Step by Step' + "\n")
file.write(' App.Console.PrintMessage(str(myObject.Placement) + " #(" + str(comptCoordinate) + ")" + "' + chr(92) + 'n")' + "\n")
file.write(' ####' + "\n")
file.write(' if createPoint == 1:' + "\n")
file.write(' point = Draft.makePoint(myObject.Placement.Base) # create point to Placement.Base' + "\n")
file.write(' Draft.autogroup(point) #' + "\n")
file.write(' FreeCAD.ActiveDocument.recompute() #' + "\n")
file.write(' ####' + "\n")
file.write(' xxKey = ""' + "\n")
file.write(' while xxKey != "S":' + "\n")
file.write(' if xxKey == "RETURN" or xxKey == "PAD_ENTER" or xxKey == "ESCAPE": break' + "\n")
file.write(' xxKey = ""' + "\n")
file.write(' Gui.updateGui() # rafraichi l''ecran' + "\n")
file.write('' + "\n")
file.write('except Exception:' + "\n")
file.write(' FreeCAD.Console.PrintError("' + chr(92) + 'n"+"Not document open, or not object selected" + "' + chr(92) + 'n")' + "\n")
file.write(' try:' + "\n")
file.write(' v.removeEventCallback("SoKeyboardEvent",c)' + "\n")
file.write(' except Exception:' + "\n")
file.write(' None' + "\n")
file.write('' + "\n")
#### macro second section end

except Exception:
App.Console.PrintError("Error write file "+"\n")
finally:
file.close()
except Exception:
App.Console.PrintError("Error Write file "+SaveName+"\n")
# print("on_PB_Save_Memorize")

def on_PB_ClearMemo(self):
global saveOnDisk
global saveListView
global countMemory
global memorySelected

try:
model = saveListView = QtGui.QStandardItemModel()
self.TE_Memorize.model().removeRows(0, countMemory)# model.rowCount()
saveOnDisk = []
self.TE_Memorize.setModel(saveListView)
countMemory = 0
memorySelected = []
self.PB_Memorize.setText("Memo")
self.PB_Memorize.setStyleSheet("Base")
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Eteint_Icon))) # icone dans une variable
except Exception:
None
# print("on_PB_ClearMemo")

def on_CB_On_Click_Apply(self):

if self.CB_On_Click_Apply.isChecked():
self.CB_On_Click_Apply.setIcon(QtGui.QIcon(QtGui.QPixmap(normalWork_Icon))) # icone dans une variable
self.CB_On_Click_Apply.setText(u"Memo on demand")
self.CB_On_Click_Apply.setToolTip(u"Memorize the coordinates on demand")
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Allume_Icon))) # icone dans une variable
self.groupBox_Data.setEnabled(True)
else:
self.CB_On_Click_Apply.setIcon(QtGui.QIcon(QtGui.QPixmap(OnClickApply_Icon))) # icone dans une variable
self.CB_On_Click_Apply.setText(u"Memo on click")
self.CB_On_Click_Apply.setToolTip(u"Memorize the coordinates on all Click Apply button")
# print("on_CB_On_Click_Apply")

def On_CB_DataInMacro(self):

if self.CB_DataInMacro.isChecked():
self.CB_DataInMacro.setIcon(QtGui.QIcon(QtGui.QPixmap(code_FC_Icon))) # icone dans une variable
self.CB_DataInMacro.setText(u"Coordinate")
self.PB_Save_Memorize.setText("Save (wr)")
self.PB_Save_Memorize.setToolTip("The file is open in mode Write" + "\n"
"If the file exist, the file is crushed" + "\n"
"")
else:
self.CB_DataInMacro.setIcon(QtGui.QIcon(QtGui.QPixmap(code_Python_Icon))) # icone dans une variable
self.CB_DataInMacro.setText(u"Macro")
self.PB_Save_Memorize.setText("Save (ap)")
self.PB_Save_Memorize.setToolTip("The file is open in mode Append" + "\n"
"If the file exist, the the data hare adding in the file" + "\n"
"")
# print("On_CB_DataInMacro")

def on_DS_Scroll_Bar(self,val):
global valeur
global myObject
global axisX, axisY, axisZ
global posX, posY, posZ
global rotAngleX, rotAngleY, rotAngleZ

valeur = val
if (myObject == "") or (valeur == 0):
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Eteint_Icon))) # icone dans une variable
self.DS_Scroll_Bar.setValue(0.0)
self.DS_Scroll_Bar.setStyleSheet("background-color: rgb(250, 88, 88)")
# self.SC_Slider_Bar.setValue(0.0)
None
else:
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Allume_Icon))) # icone dans une variable
self.DS_Scroll_Bar.setStyleSheet("Base")
self.PB_Memorize.setStyleSheet("Base")
# self.SC_Slider_Bar.setValue(valeur)
if self.CB_Position.isChecked(): # translate

if self.RB_Rotation_X.isChecked():
posX = valeur
posY = posZ = 0.0
self.LE_Increment.setText(str(round(myObject.Placement.Base[0],4) + valeur))
elif self.RB_Rotation_Y.isChecked():
posY = valeur
posX = posZ = 0.0
self.LE_Increment.setText(str(round(myObject.Placement.Base[1],4) + valeur))
elif self.RB_Rotation_Z.isChecked():
posZ = valeur
posX = posY = 0.0
self.LE_Increment.setText(str(round(myObject.Placement.Base[2],4) + valeur))
elif self.RB_Direction_D.isChecked():
posZ = valeur
posX = posY = 0.0
xD = str(round(myObject.Placement.Base[0],4))
yD = str(round(myObject.Placement.Base[1],4))
zD = str(round(myObject.Placement.Base[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")

self.label_00.setText("[Pos=(" + str(round(myObject.Placement.Base[0],2))+" , " +
str(round(myObject.Placement.Base[1],2))+" , " +
str(round(myObject.Placement.Base[2],2))+")] " +
"[Axis=("+ str(round(axisX,2)) + " , " + str(round(axisY,2)) + " , " + str(round(axisZ,2)) + ")]")

else: # rotation

if self.RB_Rotation_X.isChecked():
rotAngleX = valeur
rotAngleY = rotAngleZ = 0.0
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[0],4) + valeur))
elif self.RB_Rotation_Y.isChecked():
rotAngleY = valeur
rotAngleZ = rotAngleX = 0.0
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[1],4) + valeur))
elif self.RB_Rotation_Z.isChecked():
rotAngleZ = valeur
rotAngleX = rotAngleY = 0.0
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[2],4) + valeur))
elif self.RB_Direction_D.isChecked():
rotAngleZ = valeur
rotAngleX = rotAngleY = 0.0
xD = str(round(myObject.Placement.Rotation.toEuler()[0],4))
yD = str(round(myObject.Placement.Rotation.toEuler()[1],4))
zD = str(round(myObject.Placement.Rotation.toEuler()[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")

self.label_00.setText("[Rot=(" + str(round(rotAngleX,2)) + " , " + str(round(rotAngleY,2)) + " , " + str(round(rotAngleZ,2)) + ")] " +
"[Axis=("+ str(round(axisX,2)) + " , " + str(round(axisY,2)) + " , " + str(round(axisZ,2)) + ")]")
# print("on_DS_Scroll_Bar ", valeur)

def on_LE_Increment_Pressed(self,text):
None
# print("on_lineEdit_1_Pressed")

def on_PB_Apply_clicked(self):
global valeur
global myObject

global axisX, axisY, axisZ
global posX, posY, posZ
global rotAngleX, rotAngleY, rotAngleZ

if (myObject == "") or (valeur == 0):
self.label_00.setStyleSheet("color : #ffffff; background-color: red; font: bold 10px;") # white red bold
self.label_00.setText(" Select one Object or give one value Angle/Dimension")
FreeCAD.Console.PrintError("Select one Object or give one value Angle/Dimension" + "\n")
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Eteint_Icon))) # icone dans une variable
if valeur == 0:
self.DS_Scroll_Bar.setStyleSheet("background-color: rgb(250, 88, 88)")
else:
self.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Allume_Icon))) # icone dans une variable
if self.CB_Position.isChecked(): # translate

if self.RB_Direction_D.isChecked(): # direction
try:
selectedEdge = FreeCADGui.Selection.getSelectionEx()[1].SubObjects[0] # select one element and axis second object (2 selections)
except Exception:
try:
selectedEdge = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[1] # select one element and axis same object (2 selections)
except Exception:
try:
selectedEdge = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0] # select one element and axis same object (1 selection)
except Exception:
None
#print(selectedEdge)
pointsTrajet = []
try:
pointsTrajet = selectedEdge.discretize(Distance = 1.0) # discretize the element
except Exception:
direction = myObject.Shape.Vertexes[0].Point
pointsTrajet = direction
None
try:
direction = pointsTrajet[1].sub(pointsTrajet[0]) # search the direction line or sub
except Exception:
try:
direction = myObject.Shape.Vertexes[0].Point # direction point
except Exception:
direction = App.Vector(0.0,0.0,0.0)
myObject.Placement.Base = myObject.Placement.Base + App.Vector(direction).scale(valeur, valeur, valeur)
else:
myObject.Placement = App.Placement(App.Vector(posX, posY, posZ), App.Rotation(0.0,0.0,0.0), App.Vector(0.0,0.0,0.0)).multiply(App.ActiveDocument.getObject(myObject.Name).Placement)

if self.RB_Rotation_X.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[0],4)))
elif self.RB_Rotation_Y.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[1],4)))
elif self.RB_Rotation_Z.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[2],4)))
elif self.RB_Direction_D.isChecked():
xD = str(round(myObject.Placement.Base[0],4))
yD = str(round(myObject.Placement.Base[1],4))
zD = str(round(myObject.Placement.Base[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")

self.label_00.setText("[Pos=(" + str(round(myObject.Placement.Base[0],2))+" , " +
str(round(myObject.Placement.Base[1],2))+" , " +
str(round(myObject.Placement.Base[2],2))+")] " +
"[Axis=("+ str(round(axisX,2)) + " , " + str(round(axisY,2)) + " , " + str(round(axisZ,2)) + ")]")

else: # rotation
if self.RB_Direction_D.isChecked(): # direction
try:
selectedEdge = FreeCADGui.Selection.getSelectionEx()[1].SubObjects[0] # select one element and axis second object (2 selections)
except Exception:
try:
selectedEdge = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[1] # select one element and axis same object (2 selections)
except Exception:
try:
selectedEdge = FreeCADGui.Selection.getSelectionEx()[0].SubObjects[0] # select one element and axis same object (1 selection)
except Exception:
None
try:
direction = selectedEdge.Vertexes[1].Point.sub(selectedEdge.Vertexes[0].Point)# search the direction line or sub
except Exception:
try:
direction = objectRotation.Vertexes[0].Point
except Exception:
direction = App.Vector(0.0,0.0,0.0)
#####
# if (self.CB_Free.isChecked()):# valeur = valvaleur = 1.0
# myObject.Placement = App.Placement(App.Vector(0.0,0.0,0.0), App.Rotation(App.Vector(direction), 1), App.Vector(axisX, axisY, axisZ))#.multiply(App.ActiveDocument.getObject(myObject.Name).Placement)
# else:
# myObject.Placement = App.Placement(App.Vector(0.0,0.0,0.0), App.Rotation(App.Vector(direction), valeur), App.Vector(axisX, axisY, axisZ)).multiply(App.ActiveDocument.getObject(myObject.Name).Placement)
#####
myObject.Placement = App.Placement(App.Vector(0.0,0.0,0.0), App.Rotation(App.Vector(direction), valeur), App.Vector(axisX, axisY, axisZ)).multiply(App.ActiveDocument.getObject(myObject.Name).Placement)
else:
myObject.Placement = App.Placement(App.Vector(0.0,0.0,0.0), App.Rotation(rotAngleX, rotAngleY, rotAngleZ), App.Vector(axisX, axisY, axisZ)).multiply(App.ActiveDocument.getObject(myObject.Name).Placement) # other method

if self.RB_Rotation_X.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[0],4)))
elif self.RB_Rotation_Y.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[1],4)))
elif self.RB_Rotation_Z.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[2],4)))
elif self.RB_Direction_D.isChecked():
xD = str(round(myObject.Placement.Rotation.toEuler()[0],4))
yD = str(round(myObject.Placement.Rotation.toEuler()[1],4))
zD = str(round(myObject.Placement.Rotation.toEuler()[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")

self.label_00.setText("[Rot=(" + str(round(myObject.Placement.Rotation.toEuler()[0],2)) + " , " +
str(round(myObject.Placement.Rotation.toEuler()[1],2)) + " , " +
str(round(myObject.Placement.Rotation.toEuler()[2],2)) + ")] " +
"[Axis=("+ str(round(axisX,2))+" , "+ str(round(axisY,2))+" , "+ str(round(axisZ,2))+")]")
if self.CB_On_Click_Apply.isChecked():
self.on_PB_Memorize()

# FreeCAD.ActiveDocument.recompute()
# print("on_PB_Apply_clicked")

def on_RB_Rotation_0(self):
None
# print("on_RB_Rotation_0")

def on_RB_Rotation_X(self):
global myObject

if self.CB_Position.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[0],4))) # pos X
else:
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[0],4))) # yaw = Z
self.DS_Scroll_Bar.setValue(0.0)
# print("on_RB_Rotation_X")

def on_RB_Rotation_Y(self):
global myObject

if self.CB_Position.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[1],4))) # pos Y
else:
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[1],4))) # pitch= Y
self.DS_Scroll_Bar.setValue(0.0)
# print("on_RB_Rotation_Y")

def on_RB_Rotation_Z(self):
global myObject

if self.CB_Position.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[2],4))) # pos Z
else:
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[2],4))) # roll = X
self.DS_Scroll_Bar.setValue(0.0)
# print("on_RB_Rotation_Z")

def on_RB_Direction_D(self):
global myObject

if self.CB_Position.isChecked():
xD = str(round(myObject.Placement.Base[0],4))
yD = str(round(myObject.Placement.Base[1],4))
zD = str(round(myObject.Placement.Base[2],4))
else:
xD = str(round(myObject.Placement.Rotation.toEuler()[0],4))
yD = str(round(myObject.Placement.Rotation.toEuler()[1],4))
zD = str(round(myObject.Placement.Rotation.toEuler()[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")
self.DS_Scroll_Bar.setValue(0.0)
# print("on_RB_Direction_D")

def on_RB_CenterRot(self): # zero
global myObject
global positionMouse
global axisX, axisY, axisZ
try:
self.groupBox_Pos_Mouse.setEnabled(False)
if self.RB_Bond_Box_Center.isChecked(): # axis
axisX = myObject.Shape.BoundBox.Center.x
axisY = myObject.Shape.BoundBox.Center.y
axisZ = myObject.Shape.BoundBox.Center.z
self.label_00.setToolTip("Axis BoundBox.Center")
elif self.RB_Center_Mass.isChecked():
axisX = myObject.Shape.CenterOfMass.x
axisY = myObject.Shape.CenterOfMass.y
axisZ = myObject.Shape.CenterOfMass.z
self.label_00.setToolTip("Axis Center Of Mass")
elif self.RB_Point_Clicked.isChecked():
axisX = positionMouse[0]
axisY = positionMouse[1]
axisZ = positionMouse[2]
self.groupBox_Pos_Mouse.setEnabled(True)
self.label_00.setToolTip("Point Mouse")
except Exception:
self.label_00.setText("Error CenterRot_0")
FreeCAD.Console.PrintError("Error CenterRot_0" + "\n" + "or Bad selection" + "\n")
# print("on_RB_CenterRot")

def on_CB_Position(self):
global myObject
global posX, posY, posZ
global axisX, axisY, axisZ

if self.CB_Position.isChecked():
self.RB_Rotation_Z.setIcon(QtGui.QIcon(QtGui.QPixmap(axis_Z_Icon))) # icone dans une variable
self.RB_Rotation_X.setIcon(QtGui.QIcon(QtGui.QPixmap(axis_X_Icon))) # icone dans une variable
self.CB_Position.setIcon(QtGui.QIcon(QtGui.QPixmap(rotate_Icon))) #icone dans une variable
self.CB_Position.setToolTip(u"UnCheck for rotate the object in axis selected")
self.CB_Position.setText(u"Rotation")
self.CB_Position.setToolTip(u"Rotate the object to axis choice X, Y, Z or D")
self.groupBox_Rotation.setEnabled(False)
self.RB_Bond_Box_Center.setChecked(True)
# self.SC_Slider_Bar.setMinimum(-1000)
# self.SC_Slider_Bar.setMaximum(1000)
# self.DS_Scroll_Bar.setMinimum(-1000)
# self.DS_Scroll_Bar.setMaximum(1000)

self.groupBox_Axis.setTitle("Axis Translation")
self.RB_Rotation_Z.setText("Translation Z ") # translate
self.RB_Rotation_Y.setText("Translation Y ")
self.RB_Rotation_X.setText("Translation X ")
self.RB_Direction_D.setText("Translation D ")
self.DS_Scroll_Bar.setSuffix(" mm")

try:
self.label_00.setText("[Pl.Base=(" + str(round(myObject.Placement.Base[0],2)) + " , " +
str(round(myObject.Placement.Base[1],2)) + " , " +
str(round(myObject.Placement.Base[2],2)) + ")] " +
"[Axis=("+ str(round(axisX,2)) + " , " + str(round(axisY,2)) + " , " + str(round(axisZ,2)) + ")]")
if self.RB_Rotation_X.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[0],4)))
elif self.RB_Rotation_Y.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[1],4)))
elif self.RB_Rotation_Z.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Base[2],4)))
elif self.RB_Direction_D.isChecked():
xD = str(round(myObject.Placement.Base[0],4))
yD = str(round(myObject.Placement.Base[1],4))
zD = str(round(myObject.Placement.Base[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")
except Exception:
self.label_00.setText("Error Position_0")
FreeCAD.Console.PrintError("Error Position_0" + "\n" + "or Bad selection" + "\n")
else:
self.RB_Rotation_Z.setIcon(QtGui.QIcon(QtGui.QPixmap(axis_X_Icon))) # icone dans une variable
self.RB_Rotation_X.setIcon(QtGui.QIcon(QtGui.QPixmap(axis_Z_Icon))) # icone dans une variable
self.CB_Position.setIcon(QtGui.QIcon(QtGui.QPixmap(translate_Icon))) #icone dans une variable
self.CB_Position.setText(u"Translation")
self.CB_Position.setToolTip(u"Check for move the object to axis choice X, Y, Z or D")
self.groupBox_Rotation.setEnabled(True)
# self.SC_Slider_Bar.setMinimum(0.0)
# self.SC_Slider_Bar.setMaximum(359.0)
# self.DS_Scroll_Bar.setMinimum(0.0)
# self.DS_Scroll_Bar.setMaximum(359.0)

self.groupBox_Axis.setTitle("Axis Rotation")
self.RB_Rotation_Z.setText("Rotation(X) Roll") # rotation
self.RB_Rotation_Y.setText("Rotation(Y) Pitch")
self.RB_Rotation_X.setText("Rotation(Z) Yaw")
self.RB_Direction_D.setText("Rotation(D)")
self.DS_Scroll_Bar.setSuffix(" Degrees")

try:
self.label_00.setText("[Rot=(" + str(round(myObject.Placement.Rotation.toEuler()[0],2)) + " , " +
str(round(myObject.Placement.Rotation.toEuler()[1],2)) + " , " +
str(round(myObject.Placement.Rotation.toEuler()[2],2)) + ")] " +
"[Axis=("+str(round(axisX,2))+" , "+ str(round(axisY,2))+" , "+ str(round(axisZ,2))+")]")
if self.RB_Rotation_X.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[0],4)))
elif self.RB_Rotation_Y.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[1],4)))
elif self.RB_Rotation_Z.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[2],4)))
elif self.RB_Direction_D.isChecked():
xD = str(round(myObject.Placement.Rotation.toEuler()[0],4))
yD = str(round(myObject.Placement.Rotation.toEuler()[1],4))
zD = str(round(myObject.Placement.Rotation.toEuler()[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")
except Exception:
self.label_00.setText("Error Position_1")
FreeCAD.Console.PrintError("Error Position_0" + "\n" + "or Bad selection" + "\n")

self.DS_Scroll_Bar.setValue(0.0)
# print("on_CB_Position")

def on_CB_Point(self):
global ui
global myObject
global positionMouse
if self.RB_Bond_Box_Center.isChecked(): # axis
# if self.CB_Point.isChecked():
point = Draft.makePoint(myObject.Shape.BoundBox.Center.x, myObject.Shape.BoundBox.Center.y, myObject.Shape.BoundBox.Center.z)
point.ViewObject.PointColor = (1.0,0.0,0.0)
point.Label = "Point_BoundBox_Center"
elif self.RB_Center_Mass.isChecked():
# if self.CB_Point.isChecked():
point = Draft.makePoint(myObject.Shape.CenterOfMass.x, myObject.Shape.CenterOfMass.y, myObject.Shape.CenterOfMass.z)
point.ViewObject.PointColor = (0.0,1.0,0.0)
point.Label = "Point_CenterOfMass"
elif self.RB_Point_Clicked.isChecked():
# if self.CB_Point.isChecked():
point = Draft.makePoint(positionMouse[0], positionMouse[1], positionMouse[2])
point.ViewObject.PointColor = (0.0,0.0,1.0)
point.Label = "Point_positionMouse"
Gui.Selection.addSelection(App.ActiveDocument.getObject(myObject.Name))
FreeCAD.ActiveDocument.recompute()
# ui.on_RB_CenterRot()
# print("on_CB_Point")

def on_PB_Zero_clicked(self):
global myObject

if (myObject != ""):
try:
pl = App.Placement(App.Vector(0.0,0.0,0.0), App.Rotation(0.0, 0.0, 0.0), App.Vector(0.0, 0.0, 0.0))
myObject.Placement = pl
#FreeCAD.ActiveDocument.recompute()
if self.RB_Rotation_X.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[0],4)))
elif self.RB_Rotation_Y.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[1],4)))
elif self.RB_Rotation_Z.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[2],4)))
elif self.RB_Direction_D.isChecked():
xD = str(round(myObject.Placement.Rotation.toEuler()[0],4))
yD = str(round(myObject.Placement.Rotation.toEuler()[1],4))
zD = str(round(myObject.Placement.Rotation.toEuler()[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")
self.label_00.setText("[Rot=(" +str(round(myObject.Placement.Rotation.toEuler()[0],2))+" , "+str(round(myObject.Placement.Rotation.toEuler()[1],2))+" , "+ str(round(myObject.Placement.Rotation.toEuler()[2],2))+")] "+
"[Axis=("+str(round(myObject.Placement.Base.x,2))+" , "+ str(round(myObject.Placement.Base.y,2))+" , "+ str(round(myObject.Placement.Base.z,2))+")]")
self.DS_Scroll_Bar.setValue(0.0)
self.LE_Increment.setText(str(0.0))
#FreeCAD.ActiveDocument.recompute()
Gui.activeDocument().activeView().viewTop()
Gui.SendMsgToActiveView("ViewFit")
except Exception:
self.label_00.setText("Error Zero_0")
FreeCAD.Console.PrintError("Error Zero_0" + "\n" + "or Bad selection" + "\n")
else:
self.label_00.setStyleSheet("color : #ffffff; background-color: red; font: bold 10px;") # white red bold
self.label_00.setText(" Select one Object or give one value Angle/Dimension")
FreeCAD.Console.PrintError("Select one Object or give one value Angle/Dimension" + "\n")
# print("on_PB_Zero_clicked")

def on_PB_Original_clicked(self):
global ui
global myObject
global originalPlacement
global axisX, axisY, axisZ
global rotAngleX, rotAngleY, rotAngleZ

if (myObject != ""):
try:
rotAngleX = rotAngleY = rotAngleZ = 0.0
myObject.Placement = originalPlacement
self.DS_Scroll_Bar.setValue(0.0)
if self.RB_Rotation_X.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[0],4))) # yaw Z
elif self.RB_Rotation_Y.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[1],4))) # pitch Y
elif self.RB_Rotation_Z.isChecked():
self.LE_Increment.setText(str(round(myObject.Placement.Rotation.toEuler()[2],4))) # roll Z
elif self.RB_Direction_D.isChecked():
xD = str(round(myObject.Placement.Rotation.toEuler()[0],4))
yD = str(round(myObject.Placement.Rotation.toEuler()[1],4))
zD = str(round(myObject.Placement.Rotation.toEuler()[2],4))
self.LE_Increment.setText("(" + xD + ", " + yD + ", " + zD + ")")
ui.on_RB_CenterRot()
self.label_00.setText("[Rot=(" +str(round(myObject.Placement.Rotation.toEuler()[0],2))+" , "+str(round(myObject.Placement.Rotation.toEuler()[1],2))+" , "+ str(round(myObject.Placement.Rotation.toEuler()[2],2))+")] "+
"[Axis=("+str(round(axisX,2))+" , "+ str(round(axisY,2))+" , "+ str(round(axisZ,2))+")]")
#FreeCAD.ActiveDocument.recompute()
except Exception:
self.label_00.setText("Error Original_0")
FreeCAD.Console.PrintError("Error Original_0" + "\n" + "or Bad selection" + "\n")
else:
self.label_00.setStyleSheet("color : #ffffff; background-color: red; font: bold 10px;") # white red bold
self.label_00.setText(" Select one Object or give one value Angle/Dimension")
FreeCAD.Console.PrintError("Select one Object or give one value Angle/Dimension" + "\n")
# print("on_PB_Original_clicked")

def on_PB_Reset_clicked(self):
global ui
global originalObject
global myObject
global valeur
global posX, posY, posZ
global rotAngleX, rotAngleY, rotAngleZ
global axisX, axisY, axisZ
global countMemory

try:
for obj in FreeCAD.ActiveDocument.Objects: # deslectionne
FreeCADGui.Selection.removeSelection(obj)
except Exception:
None

if countMemory == 0:
ui.on_PB_ClearMemo

originalObject = myObject = ""
posX = posY = posZ = rotAngleX = rotAngleY = rotAngleZ = 0.0
axisX = axisY = axisZ = 0.0
valeur = 0.0

self.DS_Scroll_Bar.setStyleSheet("Base")
self.DS_Scroll_Bar.setValue(valeur)
self.DS_Scroll_Bar.setSuffix(" Degrees")
self.LE_Increment.setText(str(0.0))

self.groupBox_Axis.setTitle("Axis Rotation")
self.RB_Rotation_Z.setText("Rotation(X) Roll")
self.RB_Rotation_Y.setText("Rotation(Y) Pitch")
self.RB_Rotation_X.setText("Rotation(Z) Yaw")
self.RB_Direction_D.setText("Rotation(D) Direction")

self.groupBox_Rotation.setEnabled(False)
self.groupBox_Axis.setEnabled(False)
self.groupBox_Pos_Mouse.setEnabled(False)
self.groupBox_Work.setEnabled(False)
self.groupBox_Data.setEnabled(False)

self.DS_Pos_Mouse_X.setValue(0.0)
self.DS_Pos_Mouse_Y.setValue(0.0)
self.DS_Pos_Mouse_Z.setValue(0.0)

# self.CB_Position.setEnabled(False)
# self.CB_Position.setChecked(False)
self.CB_Position.setText(u"Translation")
self.CB_Position.setToolTip(u"Move the object to axis choice X, Y or Z")
# self.CB_Point.setEnabled(False)
# self.CB_Point.setChecked(False)
self.PB_Point.setEnabled(False)
# self.CB_Free.setEnabled(False)
# self.CB_Free.setChecked(False)

self.label_00.setStyleSheet("color : #ffffff; background-color: red; font: bold 10px;") # white red bold
self.label_00.setText(" Select one Object or give one value Angle/Dimension")

FreeCAD.Console.PrintError("Select one Object or give one value Angle/Dimension" + "\n")
FreeCAD.Console.PrintMessage("Reset" + "\n")
# print("on_PB_Reset_clicked")

def on_PB_Quit_clicked(self):
self.vueActive.removeEventCallback("SoMouseButtonEvent",self.click) # desinstalle la fonction souris
FreeCADGui.Selection.removeObserver(s) # desinstalle la fonction residente
FreeCAD.Console.PrintMessage("Quit xxxxx" + "\n")
try:
FreeCADGui.Selection.removeObserver(s) # Uninstalls resident function (desactivated for read after LeftDock RightDock)
self.window.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) # destroy
self.window.deleteLater() # destroy
self.window.destroy() # destroy
except Exception:
self.window.hide() # hide the window and close the macro
FreeCAD.Console.PrintMessage("Quit Rotate_To_Point" + "\n")

###################################################################################################
class SelObserver:
def addSelection(self, document, object, element, position): # Selection
global ui
global sourisPass
global valeur
global positionMouse
global originalObject
global myObject
global originalPlacement

global posX, posY, posZ
global rotAngleX, rotAngleY, rotAngleZ
global axisX, axisY, axisZ

if sourisPass == 0: # pour un seul passage
sourisPass == 1

sel = FreeCADGui.Selection.getSelection()[0] # select object with getSelection()
positionMouse = position
originalObject = myObject = sel
originalPlacement = sel.Shape.Placement

#longueur = (myObject.Shape.BoundBox.XLength * 0.5) # pour Axis
positionBase = originalObject.Shape.Placement.Base # Placement Vector XYZ
posX = positionBase.x
posY = positionBase.y
posZ = positionBase.z
Yaw = originalObject.Shape.Placement.Rotation.toEuler()[0] # decode angle Euler Yaw
Pitch = originalObject.Shape.Placement.Rotation.toEuler()[1] # decode angle Euler Pitch
Roll = originalObject.Shape.Placement.Rotation.toEuler()[2] # decode angle Euler Roll
rotAngleX = Yaw
rotAngleY = Pitch
rotAngleZ = Roll
axisX = axisY = axisZ = 0.0

valeur = 0.0
ui.DS_Scroll_Bar.setValue(valeur)
ui.DS_Scroll_Bar.setStyleSheet("background-color: rgb(250, 88, 88)")

ui.DS_Pos_Mouse_X.setValue(positionMouse[0])
ui.DS_Pos_Mouse_Y.setValue(positionMouse[1])
ui.DS_Pos_Mouse_Z.setValue(positionMouse[2])

ui.on_RB_CenterRot()
if ui.CB_Position.isChecked():
ui.groupBox_Rotation.setEnabled(False)
else:
ui.groupBox_Rotation.setEnabled(True)
ui.groupBox_Axis.setEnabled(True)
ui.groupBox_Work.setEnabled(True)
ui.groupBox_Data.setEnabled(True)
ui.PB_Memorize.setIcon(QtGui.QIcon(QtGui.QPixmap(memo_Allume_Icon))) # icone dans une variable
#ui.groupBox_Pos_Mouse.setEnabled(True)
ui.label_00.setStyleSheet("Base") # origin system
ui.label_00.setText("[Rot =(" + str(round(rotAngleX,2))+ " , " + str(round(rotAngleY,2)) + " , " + str(round(rotAngleZ,2)) + ")] " +
"[Axis=("+ str(round(axisX,2)) + " , " + str(round(axisY,2)) + " , " + str(round(axisZ,2)) + ")]")
ui.PB_Memorize.setStyleSheet("Base")

def clearSelection(self,doc): # Si clic sur l'ecran, effacer la selection
global ui
ui.on_PB_Reset_clicked

###################################################################################################

doc = FreeCAD.ActiveDocument
if doc == None:
doc = FreeCAD.newDocument()

try:
for obj in FreeCAD.ActiveDocument.Objects: # deselectionne
FreeCADGui.Selection.removeSelection(obj)
except Exception:
None

s=SelObserver()
FreeCADGui.Selection.addObserver(s) # installe la fonction en mode resident

if __name__ == "__main__":
MainWindow = QtWidgets.QMainWindow()
MainWindow.setObjectName("__title__") # macro internal Name
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()

}}
<translate>

==Example:== <!--T:9-->
</translate>
[[File:Macro Rotate To Point 01.gif ]]
<translate>
==Links== <!--T:10-->
</translate>
The forum [http://forum.freecadweb.org/viewtopic.php?f=8&t=20925 feature req: placement - rotate part around its midpoint]
<translate>
<!--T:11-->
My macro to Gist [https://gist.github.com/mario52a mario52a ]
</translate>
<translate>
==Version== <!--T:12-->
</translate>
<translate>


<!--T:32-->
<!--T:32-->
Line 2,504: Line 233:
<!--T:14-->
<!--T:14-->
05/03/2017 ver 00.01 : add 3 spinbox for displayed the coordinates X Y Z on click mouse
05/03/2017 ver 00.01 : add 3 spinbox for displayed the coordinates X Y Z on click mouse
</translate>


<translate>
<!--T:13-->
<!--T:13-->
04/03/2017 ver 00.00
04/03/2017 ver 00.00

Latest revision as of 10:12, 29 December 2023

Other languages:

Macro Rotate To Point

Description
Macro to rotate an object on itself with the axis of rotation the: boundbox center, center of mass, direction of wire, or last point clicked. You must save in a file all coordinate worked and save it in a file "Coordinate [(0.06,1.30,0.0),(85.0,0.0,0.0)]," or in a complete macro with different options (Create serial image) for create one animation, increase/decrease, pause, yoyo ....

Macro version: 00.11
Last modified: 2022/10/17
FreeCAD version: 0.19 and more
Download: ToolBar Icon
Author: Mario52
Author
Mario52
Download
ToolBar Icon
Links
Macro Version
00.11
Date last modified
2022/10/17
FreeCAD Version(s)
0.19 and more
Default shortcut
None
See also
None

Description

Macro to rotate an object on itself with the axis of rotation the: boundbox center, center of mass, direction, path of wire, or last point clicked. You must save in a file all coordinate worked and save it in a file "Coordinate [(0.06,1.30,0.0),(85.0,0.0,0.0)],"
or in a complete macro with different options (Create serial image) for create one animation, increase/decrease, pause, yoyo ....


Temporary code for external macro link. Do not use this code. This code is used exclusively by Addon Manager. Link for optional manual installation: Macro


# This code is copied instead of the original macro code
# to guide the user to the online download page.
# Use it if the code of the macro is larger than 64 KB and cannot be included in the wiki
# or if the RAW code URL is somewhere else in the wiki.

from PySide import QtGui, QtCore

diag = QtGui.QMessageBox(QtGui.QMessageBox.Information,
    "Information",
    "This macro must be downloaded from this link\n"
    "\n"
    "https://gist.githubusercontent.com/mario52a/2fc48333deca5a31e6232c29a9db5e4c/raw/d9419d4bb13e36940eb2f56c3c469ea4182827ee/Macro%2520Rotate%2520To%2520Point.FCMacro" + "\n"
    "\n"
    "Quit this window to access the download page")

diag.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
diag.setWindowModality(QtCore.Qt.ApplicationModal)
diag.exec_()

import webbrowser 
webbrowser.open("https://gist.githubusercontent.com/mario52a/2fc48333deca5a31e6232c29a9db5e4c/raw/d9419d4bb13e36940eb2f56c3c469ea4182827ee/Macro%2520Rotate%2520To%2520Point.FCMacro")


Usage

  1. Download the macro from the Addon Manager
  2. Execute the macro
  3. Select one object
  4. Choose one of the following orientations:

Interface Rotate to point

[1] Position Rotation

First operation

[1] Position Rotation

  • Translation: If this checkBox is checked the rotation is disabled, the object placement is done on the axis selected.

The SpinBox 1,00000 Degrees is reinitialized to 0.0 and coloured in red

  • The time passed with your favourite macro is displayed.

[2] Translation Rotation

Second operation

[2]Translation Rotation

Point Rotation

  • Boundbox Center: Select the BoundBox center to axis rotation
  • Center of Mass: Select the Center of Mass to axis rotation
  • Point Clicked: Select the last mouse click as the point for axis rotation
    • 1: select the object
    • 2: use the CTRL key to choose an extra object

Axis Rotation

  • Rotation(Z) Yaw: Yaw axis
  • Rotation(Y) Pitch: Pitch axis
  • Rotation(X) Roll: Roll axis
  • Rotation(D) Direction: Rotate around line, wire selected
  • Follow the path: Follow the path created by the wire, line, edge.
    • 1: Select the object
    • 2: Select the path

The SpinBox 1,00000 Degrees is reinitialized to 0.0 and coloured in red

Coordinates Point clicked

Rotate To Point Coordinate-On-Point-Clicked

  • DoubleSpinBox: Coordinate X on mouse click (modifiable only with the mode "Point Clicked")
  • DoubleSpinBox: Coordinate Y on mouse click (modifiable only with the mode "Point Clicked")
  • DoubleSpinBox: Coordinate Z on mouse click (modifiable only with the mode "Point Clicked")

[3] Work (Box : Cube)

Third operation

Macro Rotate To Point Work

  • View: If checked, the view return on latest view of the object selected (work with comboBox below it) and all parameters restored.
  • Point: One point is created for visualise the point rotation axis: red X, green Y, blue Z.
  • Center: One point is created on center of circle.
  • Box : List of all objects used. The choice of the object here, the zoom (if checkBox view is checked) is returned and all parameters restored.
  • 0 : Select one predefined value.
  • 1.0 : Select the saved value used.
  • - Invert: Invert the sign Positif/Negatif of the value displayed.
  • 1,00000 Degrees : Select the value.
  • Apply: Apply the modification to the object.
  • Line Edit: The line edit displays the original coordinate to axis selected + the input data given in the spinBox.
  • The coordinate is displayed

Data to save

Rotate To Point Data-To-Save

  • Window for display the coordinates stored.
  • Clear: Delete and clean the text editor.
  • Delete: Delete the selected line in the window.
  • Memo on Click: If it is checked, the placement is automatically stored in the window with the "Apply" button.
  • Memorize: Store and display the coordinate in the window, the number of coordinate stored is displayed on this button.
  • Save: Save the data in file
  • Macro:
    • Mode normal Macro the coordinate is saved in this mode : ["Body004001",(0.0,0.0,-1.5),(0.0,0.0,0.0)],
    • Mode macro 0,0 Coordinate the coordinate is saved (one object or many objects worked)
      in a complete macro directly in your macros directory with the same name of the document with extension .FCMacro
      • Options of the macro
      • __pompe____engrenage__ : Name of document
      • __22 Coordinates__ : number of coordinates
      • Type Key Q to Quit : Quit the macro
      • Type Key A to Create serial image : for create serial usage to create Animate GIF (with Gimp or other)
      • Type Key D to Decrease speed : Decrease the speed of the animation
      • Type Key I to Increase speed : Increase the speed of the animation
      • Type Key P to Pause/Continue or key RETURN or ESCAPE : Pause / Anime
      • Type Key S to Step by Step (key RETURN or ESCAPE to continue) : Step by Step
      • Type Key V to reVerse : reVerse the video
      • Type Key Y to YoYo : begin to end reverse end to begin
      • Type Key M for this message : Display this Memo
      • For use this options click mouse in the 3D view and type the key desidered
      • ____________________________
    • Mode normal Memo on Click : The data is not saved on window, you must push the Memo (2) button for save the coordinate
    • Mode Memo on Click Memo on Demand : The data is automaticly saved with all click op the Apply button
  • Copy: Memorize the content of the window in a Rotate_To_Point format : ["Body004001",(0.0,0.0,-1.5),(0.0,0.0,0.0)],

Command

Rotate To Point Command

  • Quit: Quit the macro
  • Original: After modifying the data of the object you can return to the original placement, If you have not deselected the current object.
  • 0,0,0 : This option places the object in base coordinate 0, 0, 0.
  • Reset: Reset the data in the macro and deselect the current object.

ToolBar PNG Icon and ToolBar SVG Icon

Example

Links

The forum feature req: placement - rotate part around its midpoint

My macro on Gist mario52a

Version

2022/10/17 Version=00.11 : new organization GUI, Follow the path, View on object, Button Copy, adding menu Image on macro saved, add "QtWidgets.QScrollArea()"

2021/03/08 Version=00.10 : adding zoom on object clicked, memory value, imposted values

2021/02/25 Version=00.09 : correct the macro : cause multi object possible

App.ActiveDocument.getObject(p[0]).Placement

instead

myObject.Placement

2021/02/22 Version=00.08c : correct the center facePoint (19h26 Paris)

2021/02/22 Version=00.08b : correct the center facePoint (17h23 Paris)

2021/02/22 Version=00.08 : adding save macro with multi objects moved

2021/01/24 Version=00.07 : adding option R: reverse

2021/01/12 ver 00.06 : adding the Data section and more options

2020/03/07 ver 00.05.2 : correct the bug translation delete "direction = myObject.Placement.Rotation.multVec(direction)"

2020/03/01 ver 00.05.1 : correct the position of the test "FreeCAD version"

2020/02/29 ver 00.05 : convert to Hdpi (Layout) and add Direction

06/04/2019 ver 00.04 : Python 3

29/03/2018 ver 00.03 : comment the "FreeCAD.ActiveDocument.recompute()" the change value are too slow with complex element in FreeCAD 0.17.... see FC0.17 recompute strange behaviour (regression)

27/03/2017 ver 00.02 : modify the spinbox "Pos" now accept the negative values

05/03/2017 ver 00.01 : add 3 spinbox for displayed the coordinates X Y Z on click mouse

04/03/2017 ver 00.00