Skip to content

Instantly share code, notes, and snippets.

@mario52a
Last active August 12, 2021 23:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mario52a/4aa545c23b323cf68824 to your computer and use it in GitHub Desktop.
Save mario52a/4aa545c23b323cf68824 to your computer and use it in GitHub Desktop.
This macro can rotate the screen in a defined angle and the defined axis and creates a plan to face the screen to create a form in the specified plan positions the selected face facing the screen, to detect the position of the camera, align view to face or to axis, align the object to view.
# -*- coding: utf-8 -*-
"""
***************************************************************************
* Copyright (c) 2015 2016 2017 2018 2019 2020 <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 *
***************************************************************************
"""
# FCCamera 0.5 18/03/2015 28/02/2016 06/09/2016 06_13/12/2016 07_03/01/2018 08_08/01/2018 09_08/01/2018 10+11_13/01/2018 12_01/08/2019
# 12.1_12/02/2020 13_2020/06/28 14_2020/10/20
#
#OS: Windows 10 (10.0)
#Word size of OS: 64-bit
#Word size of FreeCAD: 64-bit
#Version: 0.19.22670 (Git)
#Build type: Release
#Branch: master
#Hash: 12155f4aab09047c5697db0c1b3cf93b02edda03
#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__ = "FCCamera"
__author__ = "Mario52"
__url__ = "http://www.freecadweb.org/wiki/index.php?title=Macro_FCCamera"
__version__ = "0.14"
__date__ = "2020/10/20" #YYYY/MM/DD
__Web__ = "https://gist.github.com/mario52a/4aa545c23b323cf68824"
#
## Icon easyw-fc method
## https://forum.freecadweb.org/viewtopic.php?f=9&t=24742&start=100#p363271
import base64
FCCamera_Axis_rotation_X_BMP=\
"""
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
"""
FCCamera_Axis_rotation_Y_BMP=\
"""
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
"""
FCCamera_Axis_rotation_Z_BMP=\
"""
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
"""
FCCamera_Axis_rotation_D_BMP=\
"""
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
"""
helpIcon = [
"24 24 4 1",
" c None",
". c #016AC5",
"+ c #F8F8FF",
"@ c #FFFFFF",
"........................",
".++++++++++++++++++++++.",
".++++++++++++++++++++++.",
".++..................++.",
".++..................++.",
".++......@@@@@@......++.",
".++.....@@@@@@@@.....++.",
".++.....@@@..@@@.....++.",
".++.....@@....@@.....++.",
".++.....@@....@@.....++.",
".++...........@@.....++.",
".++..........@@@.....++.",
".++.........@@@......++.",
".++........@@@.......++.",
".++........@@........++.",
".++........@@........++.",
".++..................++.",
".++........@@........++.",
".++........@@........++.",
".++..................++.",
".++..................++.",
".++++++++++++++++++++++.",
".++++++++++++++++++++++.",
"........................"]
executeIcon = [
"24 24 3 1",
" c None",
". c #4E9A06",
"+ c #000000",
" ",
" ",
" ",
" . ",
" .+. ",
" .+.+. ",
" .+...+. ",
" .+.....+. ",
" . .+.......+.",
" .+. .+.......+. ",
" .+.+. .+.......+. ",
" .+...+. .+.......+. ",
" .+.....+.+.......+. ",
".+.......+.......+. ",
" .+.............+. ",
" .+...........+. ",
" .+.........+. ",
" .+.......+. ",
" .+.....+. ",
" .+...+. ",
" .+.+. ",
" .+. ",
" . ",
" "]
quitIcon = [
"24 24 3 1",
" c None",
". c #FFFFFF",
"+ c #CC0000",
" .... ",
"++++++++++....++++++++++",
"+.......++....++.......+",
"+.......++....++.......+",
"+.......++....++.......+",
"+...++++++....++++++...+",
"+...++++++....++++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...+++++......+++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+...++++++++++++++++...+",
"+......................+",
"+......................+",
"+......................+",
"++++++++++++++++++++++++"]
resetIcon = [
"24 24 3 1",
" c None",
". c #3465A4",
"+ c #888A85",
" ",
" ........ ",
" .++++++++. ",
" .++..+....+. ..... ",
" .+.. .+....+. .+++. ",
" .+. .+....+..+.+. ",
" ... .+....+.+.+. ",
" .+....+..+. ",
" .+......+. ",
" .+.....+. ",
" .+....+. ",
" ...... .+...+. ",
" .++++. .++++. ",
" .+...+. ...... ",
" .+....+. ",
" .+.....+. ",
" .+......+. ",
" .+..+....+. ",
" .+.+.+....+. ... ",
" .+.+..+....+. .+. ",
" .+++. .+....+. ..+. ",
" ..... .+....+..++. ",
" .++++++++. ",
" ........ "]
DetectCamera = [
"24 24 17 1",
" c None",
". c #444453",
"+ c #4245AE",
"@ c #4247D9",
"# c #4F4F8E",
"$ c #5B5A52",
"% c #676625",
"& c #6468EA",
"* c #7E81BC",
"= c #8C8B3B",
"- c #8183EE",
"; c #909074",
"> c #B8B859",
", c #B4B4DE",
"' c #CDCECE",
") c #F5F57D",
"! c #F8F86B",
" ",
" @@@@ @@@@ ",
" @---@ @---@ ",
" @@----@ @----@@ ",
" @------&@@@&------@ ",
" @-----&@@&@@&-----@ ",
" @----&@@&&&@@&----@ ",
" @---&@&&&&&&&@&---@ ",
" @&&&@#########@&&&@ ",
" ++#$%%%%%%%%%$#++ ",
" .===============. ",
" >>>>>>==%%%%%==>>>>>> ",
">>!!!!>>=$$$$$=>>!!!!>> ",
">!!!!!!>=$...$=>!!!!!!> ",
">!!!!!!>=$@@@$=>!!!!!!> ",
">!!!!!!>=#@-@#=>!!!!!!> ",
">!!!!!!>=@---@=>!!!!!!> ",
">!!!!!!>=-----=>!!!!!!> ",
">>!!!!>>=-----=>>!!!!>> ",
" >>>>>> +-----+ >>>>>> ",
" +---+ ",
" +-+ ",
" + ",
" "]
CameraToFace = [
"24 24 9 1",
" c None",
". c #05268B",
"+ c #162567",
"@ c #821E25",
"# c #3A355C",
"$ c #C62921",
"% c #4D69A2",
"& c #956F83",
"* c #6AA4EC",
" ",
" ",
" ",
" +++++++++++++++ ",
" ++%%%%%%%%%%%%++ ",
" ++%%%%%%%%%%%%+++ ",
" ++++++++++++++++.+ ",
" +**************+.+ ",
" +**************+.+ ",
" +**************+.+ ",
" +**************+.+ ",
" +*****$$$******+.+ ",
" +****$$$$$*****+.+ ",
" +***$$$$$$$****+.+ ",
" +***$$$$$$$****+.+ ",
" +***$$$$$$$****+.+ ",
" +****$$$$$*****+.+ ",
" +***$*$$$******+.+ ",
" +*$$$**********+++ ",
" +$$************++ ",
" $$++++++++++++++ ",
" $$$ ",
" $$ ",
" "]
CameraToAxis = [
"24 24 9 1",
" c None",
". c #FF0000",
"+ c #A9352E",
"@ c #7B624B",
"# c #000000",
"$ c #B1AAA0",
"% c #F3A500",
"& c #DEBF17",
"* c #ECEDE9",
" .. ",
" .. ",
" ###..####### ",
" ###&&&..&&%%%## ",
" ##&&&&&&&&%%%%#%# ",
" ###############%%# ",
" #&&&&&&&%%%%%%#%%# ",
" #&&&&&&&%%%%%%#%%# ",
" #&&&&&&&%%%%%%#%%# ",
"...#&&&&&&&%%%%%%#%%# ",
"...#&&&&&&.%%%%%%#%.....",
" #&&&&&..%%%%%%#%.....",
" #&&&&..%%%%%%%#%%# ",
" #&&&..&%%%%%%%#%%# ",
" #&&..&%%%%%%%%#%%# ",
" #&&.&&%%%%%%%%#%## ",
" #&&..&%%%%%%%%### ",
" #&&...%%%%%%%%## ",
" ###....######## ",
" .... .. ",
" .... .. ",
" .... .. ",
" . .. ",
" .. "]
AlignToView = [
"24 24 9 1",
" c None",
". c #FF0000",
"+ c #000000",
"@ c #819803",
"# c #789A70",
"$ c #AC9134",
"% c #13DB00",
"& c #BFB1A2",
"* c #E2CA0B",
" ",
" + ",
" ++%++ ",
" ++%%%%%++ ",
" ++%%%%%%%%%++ ",
" +%%%%%%%%%%%%%+ ",
" +++%%%%%%%%%+++ ",
" +%%++%%%%%++%%+ ",
" +%%%%++%++%%%%+ ",
" +%%%%%%+%%$$$$$$$$$$$$$",
" +%%%%%%+%%$***********$",
" +%%%%%%+%%$***********$",
" +%%%%%%+%%$***********$",
" +%%%.%%+%%$***********$",
" +%%%%.%+%%$***..*..***$",
" +%%%%%.+%%$****...****$",
" ++%%%%.%%$****...****$",
" ++%%+..$***..*..***$",
" ++++ ....********$",
" + $***********$",
" $***********$",
" $***********$",
" $$$$$$$$$$$$$",
" "]
PlaneAxis = [
"24 24 9 1",
" c None",
". c #CF0106",
"+ c #DB4244",
"@ c #CF5A59",
"# c #C47983",
"$ c #AD8FA3",
"% c #B7B3CA",
"& c #B1C7E2",
"* c #D6D3D7",
" .. ",
" .. ",
" .. ",
" &&&..&&& ",
" &&&&..&&&& ",
" &&&&&..&&&&& ",
" &&&&&&..&&&&&& ",
" &&&&&&&++&&&&&&& ",
" &&&&&&&&++&&&&&&&& ",
" &&&&&&&&++&&&&&&&& ",
" &&&&&&&&..&&&&&&&& ",
".......+++....+++.......",
".......+++....+++.......",
" &&&&&&&&..&&&&&&&& ",
" &&&&&&&&++&&&&&&&& ",
" &&&&&&&&++&&&&&&&& ",
" &&&&&&&++&&&&&&& ",
" &&&&&&..&&&&&& ",
" &&&&&..&&&&& ",
" &&&&..&&&& ",
" &&&..&&& ",
" .. ",
" .. ",
" .. "]
CameraPhoto = [
"24 24 9 1",
" c None",
". c #161817",
"+ c #313332",
"@ c #424544",
"# c #515452",
"$ c #686B68",
"% c #838582",
"& c #A8ABA8",
"* c #D9DBD8",
" ",
" ",
" &***& ",
" &****% ",
" %&&&&# ",
" + ++ ",
" .+#$$#. ",
" +$$$$$$$+ ",
" +#$%%%%%%%%%%%%%$$@ ",
" %&&$$%%%*$$$$%%%%$$%+ ",
" +&%%$#%+$%$$$$###%$$%+ ",
" +%%&%%@+@#$&%$###@$$%+ ",
" +$###@++@#%###@####$%+ ",
" +$###@++@$@@....++#$$+ ",
" +$###@++@#+.@#..+++$%+ ",
" +$###@++@++.%&&@+@+#%+ ",
" +$###@++@++.$*&%@@+#%+ ",
" +$###@+@#++.+$%%##+#$+ ",
" +$$####++@++.@###@+++ ",
" .+@@+. ++@@##@++ ",
" +++++++ ",
" @@@ ",
" ",
" "]
CameraPhotoOk = [
"24 24 9 1",
" c None",
". c #000100",
"+ c #161815",
"@ c #323331",
"# c #4C4E4B",
"$ c #686A67",
"% c #4B9A00",
"& c #898B88",
"* c #D8DBD7",
" %",
" %%.",
" %%.. ",
" %%..% ",
"% %%...% ",
".%% %%..%.% ",
"%..%% %%..%%.% ",
"%.%..%% %%..%%%.% ",
" %.%%..%%..%%%%.% ",
" %.%%%%..%%%%%.%&**& ",
" %.%%%%%%%%%.% &**& ",
" %.%%%%%%%.% # # ",
" %.%%%%%%.% @#$$#$ ",
" %.%%%%.% @$&&&&$ ",
" %.%%.%$&&&&$$&&&$$$",
" %.%.%&$&@$$$$##$$$#",
" %+%&$$#@#$$$####$#",
" %$###@@#$#@@@@#$#",
" $###@@#@@##@@@$#",
" $###@@#@@*&$#@##",
" $###@@#@+$&&#@##",
" $###@##@@@###@##",
" $$$$$$$$@###@# ",
" ### "]
import PySide2
from PySide2 import (QtWidgets, QtCore, QtGui)
from PySide2.QtWidgets import (QWidget, QApplication, QSlider, QGraphicsView, QGraphicsScene, QVBoxLayout, QStyle)
from PySide2.QtGui import (QPainter, QColor, QIcon)
from PySide2.QtSvg import *
import PySide2.QtXml
import Draft, Part, FreeCAD, math, PartGui, FreeCADGui, DraftVecUtils
#import os, WorkingPlane
App = FreeCAD
from math import radians, degrees, sqrt, pi, sin, cos, asin
from decimal import *
from FreeCAD import Base
from FreeCAD import Vector
import pivy
from pivy import coin
#### Detect version macro ###########################################
global switchVesionMacroSearch#; switchVesionMacroSearch = False
def vesionSearch():
import requests
contentPage = requests.get("https://wiki.freecadweb.org/Macro_" + __title__).text
for i in contentPage.split("\n"): # list page to line
if "ctEven macro-version" in i:
versionDetect = (i.split(">")[1])
if "ctEven macro-date" in i:
dateDetect = (i.split(">")[1])
try:
if (len(versionDetect) != 0) and (len(dateDetect) != 0):
break
except Exception:
None
try:
if (versionDetect == __version__) and (dateDetect == __date__):
None
else:
msg = ("New version availlable : " + "\n" +
str(versionDetect) + ":" + str(dateDetect) + "\n" +
"You can install with AddonManager")
FreeCAD.Console.PrintMessage("your actual version : " + str(__version__) + " : " + str(__date__) + "\n")
FreeCAD.Console.PrintMessage("new version availlable : " + str(versionDetect) + " : " + str(dateDetect) + "\n")
diag = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, 'New Version', msg)
diag.setWindowModality(QtCore.Qt.ApplicationModal)
diag.exec_()
except Exception:
None
return versionDetect, dateDetect
switchVesionMacroSearch = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetBool("switchVesionMacroSearch")
if switchVesionMacroSearch == True:
vesionSearch()
#### Detect version macro ###########################################
global path ; path = ""
global pathFile ; pathFile = ""
global valeur ; valeur = 0.0
global valeurV ; valeurV = 0.0
global Rname ; Rname = ["","",""]
global RnameCube; RnameCube = ""
global RnameCompound; RnameCompound = ""
global datExtract; datExtract = ""
global positionX ; positionX = 0.0
global positionY ; positionY = 0.0
global positionZ ; positionZ = 0.0
global vertexeS ; vertexeS = Vector(0.0,0.0,0.0)
global bounBoxCenter; bounBoxCenter = Vector(0.0,0.0,0.0)
global dim_Horizont ; dim_Horizont = 0
global dim_Vertical ; dim_Vertical = 0
global ori_Vertical ; ori_Vertical = 0
global ori_Horizont ; ori_Horizont = 0
global numberPhoto ; numberPhoto = 0.0
global valueTest ; valueTest = 0.0
global formatFichier; formatFichier= ".png"
global s ; s = ""
global ui ; ui = ""
global Nameelement2 ; Nameelement2 = "" # new selection
global vueView ; vueView = 0 # passe vue
global doc ; doc = FreeCAD.ActiveDocument
if doc == None:
doc = FreeCAD.newDocument() # create one document
activeView = FreeCADGui.activeDocument().activeView()
mainWindow = FreeCADGui.getMainWindow()
mdi = mainWindow.findChild(QtWidgets.QMdiArea)
mwActive = mdi.activeSubWindow()
dim_Horizont = ori_Horizont = mwActive.width()
dim_Vertical = ori_Vertical = mwActive.height()
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class SelObserver: # SelObserver
def addSelection(self,document, object, element, position): # Selection SelObserver
global positionX
global positionY
global positionZ
global vertexeS
global bounBoxCenter
positionX = position[0]
positionY = position[1]
positionZ = position[2]
bounBoxCenter = Vector(0.0,0.0,0.0)
if (element[:4] == "Edge"):
vertex = FreeCAD.ActiveDocument.getObject(object).Shape.Edges[int(element[4:])-1].Vertexes
bounBoxCenter = FreeCAD.ActiveDocument.getObject(object).Shape.Edges[int(element[4:])-1].BoundBox.Center
try:
vertexeS = vertex[1].Point.sub(vertex[0].Point)
except Exception:
vertexeS = Vector(0.0,0.0,0.0)
else:
vertexeS = Vector(0.0,0.0,0.0)
try:
bounBoxCenter = FreeCAD.ActiveDocument.getObject(object).Shape.Edges[int(element[4:])-1].BoundBox.Center
except Exception:
bounBoxCenter = FreeCAD.Vector(positionX, positionY, positionZ)
def datExtract(data):
# return a string
data = str(data)
a = ""
for i in data:
if i in ("0123456789e.- "):
a+=i
a = a.strip(" ")
a = a.split(" ")
return a
def centerBoundBoxGlobal():
global doc
doc = App.activeDocument()
objs0 = doc.findObjects()
pointMilieu = []
if len(objs0) != 0:
xMin = yMin = zMin = 0.0
xMax = yMax = zMax = 0.0
for objs in objs0:
try:
if objs.ViewObject.Visibility:
if hasattr(objs, "Shape"):
s = objs.Shape
elif hasattr(objs, "Mesh"): # upgrade with wmayer thanks #http://forum.freecadweb.org/viewtopic.php?f=13&t=22331
s = objs.Mesh
elif hasattr(objs, "Points"):
s = objs.Points
boundBox_ = s.BoundBox
extractValue = datExtract(boundBox_)
if float(extractValue[0]) < xMin:
xMin = float(extractValue[0])
if float(extractValue[1]) < yMin:
yMin = float(extractValue[1])
if float(extractValue[2]) < zMin:
zMin = float(extractValue[2])
if float(extractValue[3]) > xMax:
xMax = float(extractValue[3])
if float(extractValue[4]) > yMax:
yMax = float(extractValue[4])
if float(extractValue[5]) > zMax:
zMax = float(extractValue[5])
except Exception:
None
#### diagonale et pointMilieu
points=[FreeCAD.Vector(xMin, yMin, zMin),FreeCAD.Vector(xMax, yMax, zMax)] #diagonal
diagonal = Draft.makeWire(points,closed=False,face=False,support=None) #create diagonal line
try:
pointMilieu = diagonal.Shape.copy().discretize(3) #cut line for search center
except Exception:
None
doc.removeObject(diagonal.Name)
#Draft.makePoint(pointMilieu[1])
try:
return pointMilieu[1]
except Exception:
return FreeCAD.Vector(0.0,0.0,0.0)
else:
return FreeCAD.Vector(0.0,0.0,0.0)
def To_Face_Or_To_Axis(ToFace): # 1=NormalAt 0=Axis #Align Face selected to Face or to Axis
global vueView
global Nameelement2
global vertexeS
try:
SubElement = FreeCADGui.Selection.getSelectionEx()
Nameelement = SubElement[0].SubElementNames[0]
if Nameelement != Nameelement2:
vueView = 0
Nameelement2 = Nameelement
if ToFace == 1:
v = Gui.Selection.getSelectionEx()[0].SubObjects[0].normalAt(0,0) # NormalAt
App.Console.PrintMessage("NormalAt : ")
else:
try:
v=Gui.Selection.getSelectionEx()[0].SubObjects[0].Surface.Axis # Axis
App.Console.PrintMessage("Surface Axis : ")
except Exception:
v=vertexeS # Axis Edges
App.Console.PrintMessage("Axis Edges : ")
if vueView == 0:
r=App.Rotation(App.Vector(0,0,1),v)
App.Console.PrintMessage("0,0,1"+"\n")
elif vueView == 1:
r=App.Rotation(App.Vector(0,0,-1),v)
App.Console.PrintMessage("0,0,-1"+"\n")
elif vueView == 2:
r=App.Rotation(App.Vector(0,1,0),v)
App.Console.PrintMessage("0,1,0"+"\n")
elif vueView == 3:
r=App.Rotation(App.Vector(0,-1,0),v)
App.Console.PrintMessage("0,-1,0"+"\n")
elif vueView == 4:
r=App.Rotation(App.Vector(1,0,0),v)
App.Console.PrintMessage("1,0,0"+"\n")
elif vueView == 5:
r=App.Rotation(App.Vector(-1,0,0),v)
App.Console.PrintMessage("-1,0,0"+"\n")
vueView = -1
Gui.ActiveDocument.ActiveView.setCameraOrientation(r.Q)#
vueView += 1
except:
App.Console.PrintError("Select a face"+"\n")
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
global path
global pathFile
global valeur
global ori_Horizont
global ori_Vertical
global numberPhoto
self.window = MainWindow
#################################################################################
#path = FreeCAD.ConfigGet("AppHomePath")
#path = FreeCAD.ConfigGet("UserAppData")
#path = "your path"
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path
path = param.GetString("MacroPath","") + "/" # macro path
path = path.replace("\\","/") #pathFile =
# App.Console.PrintMessage("Path locality to FCCamera.....images.png [ " + path + " ]"+"\n")
#################################################################################
MainWindow.setObjectName(_fromUtf8("MainWindow"))
# MainWindow.resize(200, 625)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName(_fromUtf8("centralWidget"))
self.FontImpost = "Arial"
# #self.xxxx.setFont(QtGui.QFont(self.FontImpost,weight=QtGui.QFont.Bold)) # Bold
self.groupBox_00 = QtWidgets.QGroupBox()
####
self.groupBox_001 = QtWidgets.QGroupBox()
self.label_02 = QtWidgets.QLabel()
### ---graphicsView---
self.graphicsView = QtWidgets.QGraphicsView()
self.graphicsView.setFrameShape(QtWidgets.QFrame.StyledPanel)
pic = QtGui.QPixmap()
pic.loadFromData(base64.b64decode(FCCamera_Axis_rotation_X_BMP))
self.scene = QtWidgets.QGraphicsScene()
self.scene.addPixmap(QtGui.QPixmap(pic))
self.graphicsView.setScene(ui.scene)
### ---graphicsView---
####
self.groupBox_002 = QtWidgets.QGroupBox()
self.DS_Angle = QtWidgets.QDoubleSpinBox()
self.DS_Angle.setAlignment(QtCore.Qt.AlignCenter)
self.DS_Angle.setDecimals(4)
self.DS_Angle.setMinimum(-359.0)
self.DS_Angle.setMaximum(359.0)
self.DS_Angle.setSuffix(" degrees")
self.DS_Angle.setSingleStep(1.0)
self.DS_Angle.valueChanged.connect(self.on_DS_Angle_valueChanged) #connection DS_Angle
self.CB_Multiply_10 = QtWidgets.QCheckBox()
self.CB_Multiply_10.clicked.connect(self.on_CB_Multiply_10) #connection checkBox
self.label_03 = QtWidgets.QLabel()
self.RB_Angle_X = QtWidgets.QRadioButton()
self.RB_Angle_X.setFont(QtGui.QFont(self.FontImpost,weight=QtGui.QFont.Bold)) # Bold
self.RB_Angle_X.setStyleSheet("color : #ff0000") # Color text
self.RB_Angle_X.setMouseTracking(True)
self.RB_Angle_X.setChecked(True)
self.RB_Angle_X.clicked.connect(self.on_RB_Angle_X_clicked)
self.RB_Angle_Y = QtWidgets.QRadioButton()
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_Angle_Y.clicked.connect(self.on_RB_Angle_Y_clicked)
self.RB_Angle_Z = QtWidgets.QRadioButton()
self.RB_Angle_Z.setStyleSheet("color : #0000ff") # Color text
self.RB_Angle_Z.setFont(QtGui.QFont(self.FontImpost,weight=QtGui.QFont.Bold)) # Bold
self.RB_Angle_Z.clicked.connect(self.on_RB_Angle_Z_clicked)
self.RB_Direction = QtWidgets.QRadioButton()
self.RB_Direction.setStyleSheet("color : #000066") # Color text
self.RB_Direction.setFont(QtGui.QFont(self.FontImpost,weight=QtGui.QFont.Bold)) # Bold
self.RB_Direction.clicked.connect(self.on_RB_Direction_clicked)
self.PB_Accept_View = QtWidgets.QPushButton()
self.PB_Accept_View.setIcon(QtGui.QIcon(QtGui.QPixmap(executeIcon)))# execute icone dans une variable
self.PB_Accept_View.clicked.connect(self.on_PB_Accept_View_clicked)
####
self.groupBox_003 = QtWidgets.QGroupBox()
#self.groupBox_003.setVisible(False)
self.PB_Detect_Camera = QtWidgets.QPushButton()
self.PB_Detect_Camera.setIcon(QtGui.QIcon(QtGui.QPixmap(DetectCamera))) # DetectCamera icone dans une variable
self.PB_Detect_Camera.clicked.connect(self.on_PB_Detect_Camera_clicked)
self.label_04 = QtWidgets.QLabel()
self.PB_To_Face = QtWidgets.QPushButton()
self.PB_To_Face.setIcon(QtGui.QIcon(QtGui.QPixmap(CameraToFace))) # CameraToFace icone dans une variable
self.PB_To_Face.clicked.connect(self.on_PB_To_Face_clicked) # align view to face Face
self.PB_To_Axis = QtWidgets.QPushButton()
self.PB_To_Axis.setIcon(QtGui.QIcon(QtGui.QPixmap(CameraToAxis))) # CameraToAxis icone dans une variable
self.PB_To_Axis.clicked.connect(self.on_PB_To_Axis_clicked) # Align view to face Axis
self.PB_Align_O_To_View = QtWidgets.QPushButton()
self.PB_Align_O_To_View.setIcon(QtGui.QIcon(QtGui.QPixmap(AlignToView))) # AlignToView icone dans une variable
self.PB_Align_O_To_View.clicked.connect(self.on_PB_Align_O_To_View_clicked) # Align object to view
####
self.groupBox_004 = QtWidgets.QGroupBox()
self.PB_Create_Plane = QtWidgets.QPushButton()
self.PB_Create_Plane.setIcon(QtGui.QIcon(QtGui.QPixmap(PlaneAxis))) # PlaneAxis icone dans une variable
self.PB_Create_Plane.clicked.connect(self.on_PB_Create_Plane_clicked) # create plane
self.RB_01_Plane_Point = QtWidgets.QRadioButton()
self.RB_01_Plane_Point.setChecked(True)
self.RB_02_Plane_Face = QtWidgets.QRadioButton()
self.RB_03_Plane_CMass = QtWidgets.QRadioButton()
self.RB_04_Center_BBox = QtWidgets.QRadioButton()
####
self.groupBox_005 = QtWidgets.QGroupBox()
self.PB_Reset = QtWidgets.QPushButton(self.centralWidget)
self.PB_Reset.setIcon(QtGui.QIcon(QtGui.QPixmap(resetIcon))) # reset icone dans une variable
self.PB_Reset.clicked.connect(self.on_PB_Reset_clicked) # refresh
self.PB_Photo = QtWidgets.QPushButton()
self.PB_Photo.setIcon(QtGui.QIcon(QtGui.QPixmap(CameraPhoto))) # Camera icone dans une variable
self.PB_Photo.clicked.connect(self.on_PB_Photo_clicked)
self.PB_Quit = QtWidgets.QPushButton()
self.PB_Quit.setIcon(QtGui.QIcon(QtGui.QPixmap(quitIcon))) # quit icone dans une variable
self.PB_Quit.clicked.connect(self.on_PB_Quit_clicked) # quit
self.PB_Help = QtWidgets.QPushButton()
self.PB_Help.setIcon(QtGui.QIcon(QtGui.QPixmap(helpIcon))) # icone dans une variable help
self.PB_Help.clicked.connect(self.on_PB_Help) ###
####
self.groupBox_00PH = QtWidgets.QGroupBox()
self.groupBox_00PH.setVisible(False)
####
self.groupBox_00PH01 = QtWidgets.QGroupBox()
self.CBox_01_Ecran = QtWidgets.QComboBox()
# self.CBox_01_Ecran.setCurrentIndex(0)
# CBox_01_Ecran = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetInt("CBox_01_Ecran")#
# print(CBox_01_Ecran)
# self.CBox_01_Ecran.setCurrentIndex(int(CBox_01_Ecran))
self.CBox_01_Ecran.addItem(_fromUtf8("Actual"))
self.CBox_01_Ecran.addItem(_fromUtf8("Icon 16 x 16"))
self.CBox_01_Ecran.addItem(_fromUtf8("Icon 32 x 32"))
self.CBox_01_Ecran.addItem(_fromUtf8("Icon 64 x 64"))
self.CBox_01_Ecran.addItem(_fromUtf8("Icon 128 x 128"))
self.CBox_01_Ecran.addItem(_fromUtf8("CGA 320 x 200"))
self.CBox_01_Ecran.addItem(_fromUtf8("QVGA 320 x 240"))
self.CBox_01_Ecran.addItem(_fromUtf8("VGA 640 x 480"))
self.CBox_01_Ecran.addItem(_fromUtf8("SVGA 800 x 600"))
self.CBox_01_Ecran.addItem(_fromUtf8("XGA 1024 x 768"))
self.CBox_01_Ecran.addItem(_fromUtf8("XGA+ 1152 x 864"))
self.CBox_01_Ecran.addItem(_fromUtf8("SXGA 1280 x 1024"))
self.CBox_01_Ecran.addItem(_fromUtf8("SXGA+ 1400 x 1050"))
self.CBox_01_Ecran.addItem(_fromUtf8("UXGA 1600 x 1200"))
self.CBox_01_Ecran.addItem(_fromUtf8("QXGA 2048 x 1536"))
self.CBox_01_Ecran.addItem(_fromUtf8("Free"))
QtCore.QObject.connect(self.CBox_01_Ecran, QtCore.SIGNAL("currentIndexChanged(QString)"), self.SIGNAL_CBox_01_Ecran_Changed)
self.DS_01_X = QtWidgets.QSpinBox()
self.DS_01_X.setMinimum(1)
self.DS_01_X.setMaximum(ori_Horizont)
self.DS_01_X.setSingleStep(1)
self.DS_01_X.setValue(ori_Horizont)
self.DS_01_X.valueChanged.connect(self.on_DS_01_X_valueChanged) #connection doubleSpinBox
self.label_05 = QtWidgets.QLabel()
self.label_05.setStyleSheet("color : #ff0000") # Color text
self.label_05.setFont(QtGui.QFont(self.FontImpost,weight=QtGui.QFont.Bold)) # Bold
self.DS_02_Y = QtWidgets.QSpinBox()
self.DS_02_Y.setMinimum(1)
self.DS_02_Y.setMaximum(ori_Vertical)
self.DS_02_Y.setSingleStep(1)
self.DS_02_Y.setValue(ori_Vertical)
self.DS_02_Y.valueChanged.connect(self.on_DS_02_Y_valueChanged) #connection doubleSpinBox
self.label_06 = QtWidgets.QLabel()
self.label_06.setStyleSheet("color : #008700") # Color text
self.label_06.setFont(QtGui.QFont(self.FontImpost,weight=QtGui.QFont.Bold)) # Bold
self.label_07 = QtWidgets.QLabel()
self.PB_Photo_Adjust = QtWidgets.QPushButton()
self.PB_Photo_Adjust.setVisible(False)
# self.PB_Photo_Adjust.setIcon(QtGui.QIcon(path + "FCCamera_07.png"))
self.PB_Photo_Adjust.clicked.connect(self.on_PB_Photo_Adjust_clicked)
self.label_08 = QtWidgets.QLabel()
self.CBox_02_FileFormat = QtWidgets.QComboBox()
# CBox_02_FileFormat = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetInt("CBox_02_FileFormat")#
# print(CBox_02_FileFormat)
# self.CBox_02_FileFormat.setCurrentIndex(int(CBox_02_FileFormat))
self.CBox_02_FileFormat.addItem(_fromUtf8("BMP *.bmp"))
self.CBox_02_FileFormat.addItem(_fromUtf8("ICO *.ico"))
self.CBox_02_FileFormat.addItem(_fromUtf8("JPEG *.jpeg"))
self.CBox_02_FileFormat.addItem(_fromUtf8("JPG *.jpg"))
self.CBox_02_FileFormat.addItem(_fromUtf8("PNG *.png"))
self.CBox_02_FileFormat.addItem(_fromUtf8("PPM *.ppm"))
self.CBox_02_FileFormat.addItem(_fromUtf8("TIF *.tif"))
self.CBox_02_FileFormat.addItem(_fromUtf8("TIFF *.tiff"))
self.CBox_02_FileFormat.addItem(_fromUtf8("XBM *.xbm"))
self.CBox_02_FileFormat.addItem(_fromUtf8("XPM *.xpm"))
#self.CBox_02_FileFormat.addItem(_fromUtf8("GIF *.gif"))
QtCore.QObject.connect(self.CBox_02_FileFormat, QtCore.SIGNAL("currentIndexChanged(QString)"), self.SIGNAL_CBox_02_FileFormat_Changed)
####
self.groupBox_00PH02 = QtWidgets.QGroupBox()
self.RB_01_Actual = QtWidgets.QRadioButton()
self.RB_01_Actual.setChecked(True)
# self.RB_01_Actual.clicked.connect(self.on_RB_01_Actual_clicked)
self.RB_02_White = QtWidgets.QRadioButton()
# self.RB_02_White.clicked.connect(self.on_RB_02_White_clicked)
self.RB_03_Black = QtWidgets.QRadioButton()
# self.RB_03_Black.clicked.connect(self.on_RB_03_Black_clicked)
self.RB_04_Transparent = QtWidgets.QRadioButton()
# self.RB_04_Transparent.clicked.connect(self.on_RB_04_Transparent_clicked)
####
self.groupBox_00PH03 = QtWidgets.QGroupBox()
self.PB_Photo_Launch = QtWidgets.QPushButton()
self.PB_Photo_Launch.setIcon(QtGui.QIcon(QtGui.QPixmap(CameraPhotoOk)))# execute icone dans une variable
self.PB_Photo_Launch.clicked.connect(self.on_PB_Photo_Launch_clicked)
self.PB_Photo_Reset = QtWidgets.QPushButton()
self.PB_Photo_Reset.setIcon(QtGui.QIcon(QtGui.QPixmap(resetIcon))) # reset icone dans une variable
self.PB_Photo_Reset.clicked.connect(self.on_PB_Photo_Reset_clicked)
self.PB_Photo_Quit = QtWidgets.QPushButton()
# self.PB_Photo_Quit.setIcon(QtGui.QIcon(QtGui.QPixmap(quitIcon))) # quit icone dans une variable
iconRotate = QtGui.QPixmap(quitIcon).transformed(QtGui.QTransform().rotate(-90), QtCore.Qt.SmoothTransformation)#Rotation
self.PB_Photo_Quit.setIcon(iconRotate)
self.PB_Photo_Quit.clicked.connect(self.on_PB_Photo_Quit_clicked)
#####
#### GridLayout begin ######
self.grid0 = QtWidgets.QGridLayout(self.centralWidget)
self.grid0.setContentsMargins(10, 10, 10, 10)
self.grid0.addWidget(self.groupBox_00, 0, 0, 1, 1)
self.grid_00 = QtWidgets.QGridLayout(self.groupBox_00)
####
self.gridLayout_3 = QtWidgets.QGridLayout(self.groupBox_001)
self.gridLayout_3.setContentsMargins(10, 10, 10, 10)
self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
self.grid_00.addWidget(self.groupBox_001, 0, 0, 1, 1)
####
self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox_002)
self.gridLayout_4.setContentsMargins(10, 10, 10, 10)
self.gridLayout_4.addWidget(self.label_02, 0, 0, 1, 4)
self.gridLayout_4.addWidget(self.DS_Angle, 1, 0, 1, 3)
self.gridLayout_4.addWidget(self.CB_Multiply_10, 1, 3, 1, 1)
self.gridLayout_4.addWidget(self.label_03, 2, 0, 1, 1)
self.gridLayout_4.addWidget(self.RB_Angle_X, 3, 0, 1, 1)
self.gridLayout_4.addWidget(self.RB_Angle_Y, 3, 1, 1, 1)
self.gridLayout_4.addWidget(self.RB_Angle_Z, 3, 2, 1, 1)
self.gridLayout_4.addWidget(self.RB_Direction, 3, 3, 1, 1)
self.gridLayout_4.addWidget(self.PB_Accept_View, 4, 0, 1, 4)
self.grid_00.addWidget(self.groupBox_002, 1, 0, 1, 1)
####
self.gridLayout_5 = QtWidgets.QGridLayout(self.groupBox_003)
self.gridLayout_5.setContentsMargins(10, 10, 10, 10)
self.gridLayout_5.addWidget(self.PB_Detect_Camera, 0, 0, 1, 2)
self.gridLayout_5.addWidget(self.label_04, 1, 0, 1, 2)
self.gridLayout_5.addWidget(self.PB_To_Face, 2, 0, 1, 1)
self.gridLayout_5.addWidget(self.PB_To_Axis, 2, 1, 1, 1)
self.gridLayout_5.addWidget(self.PB_Align_O_To_View, 3, 0, 1, 2)
self.grid_00.addWidget(self.groupBox_003, 2, 0, 1, 1)
####
self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_004)
self.gridLayout_6.setContentsMargins(10, 10, 10, 10)
self.gridLayout_6.addWidget(self.PB_Create_Plane, 0, 0, 1, 4)
self.gridLayout_6.addWidget(self.RB_01_Plane_Point, 1, 0, 1, 1)
self.gridLayout_6.addWidget(self.RB_02_Plane_Face, 1, 1, 1, 1)
self.gridLayout_6.addWidget(self.RB_03_Plane_CMass, 1, 2, 1, 1)
self.gridLayout_6.addWidget(self.RB_04_Center_BBox, 1, 3, 1, 1)
self.grid_00.addWidget(self.groupBox_004, 3, 0, 1, 1)
####
self.gridLayout_7 = QtWidgets.QGridLayout(self.groupBox_005)
self.gridLayout_7.setContentsMargins(10, 10, 10, 10)
self.gridLayout_7.addWidget(self.PB_Reset, 0, 0, 1, 1)
self.gridLayout_7.addWidget(self.PB_Photo, 0, 1, 1, 1)
self.gridLayout_7.addWidget(self.PB_Quit, 0, 2, 1, 1)
self.gridLayout_7.addWidget(self.PB_Help, 0, 3, 1, 1)
self.grid_00.addWidget(self.groupBox_005, 4, 0, 1, 1)
####
#####photo
self.gridLayout_9 = QtWidgets.QGridLayout(self.groupBox_00PH)
self.gridLayout_11 = QtWidgets.QGridLayout(self.groupBox_00PH01)
self.gridLayout_11.setContentsMargins(10, 10, 10, 10)
self.gridLayout_11.addWidget(self.CBox_01_Ecran, 0, 0, 1, 4)
self.gridLayout_11.addWidget(self.DS_01_X, 1, 0, 1, 1)
self.gridLayout_11.addWidget(self.label_05, 1, 1, 1, 1)
self.gridLayout_11.addWidget(self.DS_02_Y, 1, 2, 1, 1)
self.gridLayout_11.addWidget(self.label_06, 1, 3, 1, 1)
self.gridLayout_11.addWidget(self.CBox_02_FileFormat, 2, 0, 1, 4)
self.gridLayout_11.addWidget(self.label_07, 3, 0, 1, 2)
self.gridLayout_11.addWidget(self.PB_Photo_Adjust, 3, 2, 1, 2)
self.gridLayout_11.addWidget(self.label_08, 4, 0, 1, 4)
self.gridLayout_9.addWidget(self.groupBox_00PH01, 0, 0, 1, 1)
####
self.gridLayout_8 = QtWidgets.QGridLayout(self.groupBox_00PH02)
self.gridLayout_8.setContentsMargins(10, 10, 10, 10)
self.gridLayout_8.addWidget(self.RB_01_Actual, 0, 0, 1, 1)
self.gridLayout_8.addWidget(self.RB_02_White, 0, 1, 1, 1)
self.gridLayout_8.addWidget(self.RB_03_Black, 0, 2, 1, 1)
self.gridLayout_8.addWidget(self.RB_04_Transparent, 0, 3, 1, 1)
self.gridLayout_9.addWidget(self.groupBox_00PH02, 1, 0, 1, 1)
####
self.gridLayout_10 = QtWidgets.QGridLayout(self.groupBox_00PH03)
self.gridLayout_10.setContentsMargins(10, 10, 10, 10)
self.gridLayout_10.addWidget(self.PB_Photo_Reset, 0, 1, 1, 1)
self.gridLayout_10.addWidget(self.PB_Photo_Quit, 0, 2, 1, 1)
self.gridLayout_10.addWidget(self.PB_Photo_Launch, 0, 3, 1, 1)
self.gridLayout_9.addWidget(self.groupBox_00PH03, 2, 0, 1, 1)
self.grid_00.addWidget(self.groupBox_00PH, 2, 0, 1, 1)
#### GridLayout end ######
MainWindow.setCentralWidget(self.centralWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle("FCCamera")
MainWindow.setWindowIcon(QtGui.QIcon(path+'FCCamera_00.png')) # change l'icone de la fenetre principale
MainWindow.setWindowFlags(PySide2.QtCore.Qt.WindowStaysOnTopHint) # PySide cette fonction met la fenetre en avant
_translate = QtCore.QCoreApplication.translate
global numberPhoto
global ori_Horizont
global ori_Vertical
self.groupBox_00.setTitle(_translate("MainWindow", "Version : " + __version__ + " : " + __date__) + " (rmu)")
self.groupBox_001.setTitle(_translate("MainWindow", "View"))
self.groupBox_002.setTitle(_translate("MainWindow", "Camera of Axis"))
####
self.CB_Multiply_10.setText(_translate("MainWindow", "Step by 10"))
self.CB_Multiply_10.setToolTip(_translate("MainWindow", "If checked the value is Multiply by 10"))
self.label_02.setText(_translate("MainWindow", "Angle rotation Axis in degrees"))
self.DS_Angle.setToolTip(_translate("MainWindow", "Enter the angle of rotation in degrees.\n"
"The given angle is added to the angle of the current view"))
self.label_03.setText(_translate("MainWindow", "Axe of rotation"))
self.RB_Angle_X.setText(_translate("MainWindow", "X"))
self.RB_Angle_X.setToolTip(_translate("MainWindow", "Rotation of the camera on the X axis"))
self.RB_Angle_Y.setText(_translate("MainWindow", "Y"))
self.RB_Angle_Y.setToolTip(_translate("MainWindow", "Rotation of the camera on the Y axis"))
self.RB_Angle_Z.setText(_translate("MainWindow", "Z"))
self.RB_Angle_Z.setToolTip(_translate("MainWindow", "Rotation of the camera on the Z axis"))
self.RB_Direction.setText(_translate("MainWindow", "D"))
self.RB_Direction.setToolTip(_translate("MainWindow", "Rotation of the camera on the Direction axis" + "\n"
"to edge selected or point selected" + "\n"
"If the point are selected the mouse coordinates are used"))
self.PB_Accept_View.setText(_translate("MainWindow", "Accept the rotation"))
self.PB_Accept_View.setToolTip(_translate("MainWindow", "Accept the view given"))
####
self.groupBox_003.setTitle(_translate("MainWindow", "Virtual"))
self.PB_Detect_Camera.setText(_translate("MainWindow", "Detect camera orientation"))
self.PB_Detect_Camera.setToolTip(_translate("MainWindow", "Detect the position of the camera\n"
" The returned value is the value provided by the function getCameraOrientation()"))
self.label_04.setText(_translate("MainWindow", "Align view :"))
self.PB_To_Face.setText(_translate("MainWindow", "To Face."))
self.PB_To_Face.setToolTip(_translate("MainWindow", "Align the view to the selected face \n"
"Click and repeat the click for NormalAt : \n"
"(0,0,1) (0,0,-1) (0,1,0) (0,-1,0) (1,0,0) (-1,0,0)"))
self.PB_To_Axis.setText(_translate("MainWindow", "To Axis."))
self.PB_To_Axis.setToolTip(_translate("MainWindow", "Align the view to Axis face selected \n"
"Click and repeat the click for Surface Axis : \n"
"(0,0,1) (0,0,-1) (0,1,0) (0,-1,0) (1,0,0) (-1,0,0)"))
self.PB_Align_O_To_View.setText(_translate("MainWindow", "Align Object to View"))
self.PB_Align_O_To_View.setToolTip(_translate("MainWindow", "Align the object selected to the actual view \n"
"The changed values are : Rotation Axis((X, Y, Z), Angle) \n"
"Same Euler angles : Yaw, Pitch, Roll \n The Translation is not modify"))
####
self.groupBox_004.setTitle(_translate("MainWindow", "Plane"))
self.PB_Create_Plane.setText(_translate("MainWindow", "Create plane of view."))
self.PB_Create_Plane.setToolTip(_translate("MainWindow", "A circular plane is created facing the screen to mouse click coordinates on an object \n"
"The radius of the plane is equal to the maximum dimension of BoundBox \n"
"If no object is selected, the plane is created to 0, 0, 0 coordinates with a radius of 20 mm"))
self.RB_01_Plane_Point.setText(_translate("MainWindow", "To Point"))
self.RB_01_Plane_Point.setToolTip(_translate("MainWindow", "Crate plane to Point mouse click"))
self.RB_02_Plane_Face.setText(_translate("MainWindow", "Center Face"))
self.RB_02_Plane_Face.setToolTip(_translate("MainWindow", "Crate plane to Center face"))
self.RB_03_Plane_CMass.setText(_translate("MainWindow", "Center Mass"))
self.RB_03_Plane_CMass.setToolTip(_translate("MainWindow", "Crate plane to Center mass"))
self.RB_04_Center_BBox.setText(_translate("MainWindow", "Center BBox"))
self.RB_04_Center_BBox.setToolTip(_translate("MainWindow", "Crate plane to Center bounding Box"))
####
self.groupBox_005.setTitle(_translate("MainWindow", "Command"))
self.PB_Reset.setText(_translate("MainWindow", "Reset"))
self.PB_Reset.setToolTip(_translate("MainWindow", "Refresh alls"))
self.PB_Photo.setText(_translate("MainWindow", "Photo"))
self.PB_Photo.setToolTip(_translate("MainWindow", "Create serial photo for create animation" + "\n"
"Give the angle rotation desired" + "\n"
"Number image = 360 / Angle degrees rotation" + "\n" + "\n"
"Modify your window 3DView to the desirate dimension" + "\n"
"Click the Accept the rotation for verify if the object rotation is good"))
self.PB_Quit.setText(_translate("MainWindow", "Quit"))
self.PB_Quit.setToolTip(_translate("MainWindow", "Quit FCCamera"))
self.PB_Help.setText(_translate("MainWindow", "Help"))
self.PB_Help.setToolTip(_translate("MainWindow", "Help on line " + __version__ + " " + __date__ + " rmu"))
#####
##### Photo
self.groupBox_00PH.setTitle(_translate("MainWindow", "Photo"))
self.groupBox_00PH01.setTitle(_translate("MainWindow", "Definition"))
self.groupBox_00PH01.setToolTip(_translate("MainWindow", "Definition image"))
####
self.CBox_01_Ecran.setCurrentIndex(0)
#CBox_01_Ecran = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetInt("CBox_01_Ecran")#
#print(CBox_01_Ecran)
#self.CBox_01_Ecran.setCurrentIndex(int(CBox_01_Ecran))
self.CBox_01_Ecran.setItemText(0 ,"Actual")
self.CBox_01_Ecran.setItemText(1 ,"Icon 16 x 16")
self.CBox_01_Ecran.setItemText(2 ,"Icon 32 x 32")
self.CBox_01_Ecran.setItemText(3 ,"Icon 64 x 64")
self.CBox_01_Ecran.setItemText(4 ,"Icon 128 x 128")
self.CBox_01_Ecran.setItemText(5 ,"CGA 320 x 200")
self.CBox_01_Ecran.setItemText(6 ,"QVGA 320 x 240")
self.CBox_01_Ecran.setItemText(7 ,"VGA 640 x 480")
self.CBox_01_Ecran.setItemText(8 ,"SVGA 800 x 600")
self.CBox_01_Ecran.setItemText(9 ,"XGA 1024 x 768")
self.CBox_01_Ecran.setItemText(10,"XGA+ 1152 x 864")
self.CBox_01_Ecran.setItemText(11,"SXGA 1280 x 1024")
self.CBox_01_Ecran.setItemText(12,"SXGA+ 1400 x 1050")
self.CBox_01_Ecran.setItemText(13,"UXGA 1600 x 1200")
self.CBox_01_Ecran.setItemText(14,"QXGA 2048 x 1536")
self.CBox_01_Ecran.setItemText(15,"Free")
self.DS_01_X.setToolTip(_translate("MainWindow", "Value X"))
self.label_05.setText(_translate("MainWindow", "X"))
self.label_05.setToolTip(_translate("MainWindow", "Definition X image"))
self.DS_02_Y.setToolTip(_translate("MainWindow", "Value Y"))
self.label_06.setText(_translate("MainWindow", "Y"))
self.label_06.setToolTip(_translate("MainWindow", "Definition Y image"))
self.label_07.setText(_translate("MainWindow", "Number images : " + str(numberPhoto)))
self.label_07.setToolTip(_translate("MainWindow", "Number image theoretic"))
self.PB_Photo_Adjust.setText(_translate("MainWindow", "Adj."))
self.PB_Photo_Adjust.setToolTip(_translate("MainWindow", "Adjust the definition on int number"))
self.PB_Photo_Adjust.setToolTip(_translate("MainWindow", "Adjust the number image to 360 degrees"))
self.label_08.setText(_translate("MainWindow", ""))
self.CBox_02_FileFormat.setCurrentIndex(4)
#CBox_02_FileFormat = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetInt("CBox_02_FileFormat")#
#print(CBox_02_FileFormat)
#self.CBox_02_FileFormat.setCurrentIndex(int(CBox_02_FileFormat))
self.CBox_02_FileFormat.setItemText(0,"BMP *.bmp")
self.CBox_02_FileFormat.setItemText(1,"ICO *.ico")
self.CBox_02_FileFormat.setItemText(2,"JPEG *.jpeg")
self.CBox_02_FileFormat.setItemText(3,"JPG *.jpg")
self.CBox_02_FileFormat.setItemText(4,"PNG *.png")
self.CBox_02_FileFormat.setItemText(5,"PPM *.ppm")
self.CBox_02_FileFormat.setItemText(6,"TIF *.tif")
self.CBox_02_FileFormat.setItemText(7,"TIFF *.tiff")
self.CBox_02_FileFormat.setItemText(8,"XBM *.xbm")
self.CBox_02_FileFormat.setItemText(9,"XPM *.xpm")
#self.CBox_02_FileFormat.setItemText(10,"GIF *.gif")
####
self.groupBox_00PH02.setTitle("BackGround image")
self.groupBox_00PH02.setToolTip(_translate("MainWindow", "Choice of property backGround image" + "\n"
"It is possible that the backGround does not appear in the desired color" + "\n"
"in this case do a test in FreeCAD :" + "\n"
"Menu > Tools > Save picture > Extended > Image properties"))
self.RB_01_Actual.setText(_translate("MainWindow", "Current"))
self.RB_01_Actual.setToolTip(_translate("MainWindow", "BackGround image in Actual color"))
self.RB_02_White.setText(_translate("MainWindow", "White"))
self.RB_02_White.setToolTip(_translate("MainWindow", "BackGround image in White"))
self.RB_03_Black.setText(_translate("MainWindow", "Black"))
self.RB_03_Black.setToolTip(_translate("MainWindow", "BackGround image in Black"))
self.RB_04_Transparent.setText(_translate("MainWindow", "Transparent"))
self.RB_04_Transparent.setToolTip(_translate("MainWindow", "BackGround image in Transparent"))
####
self.groupBox_00PH03.setTitle(_translate("MainWindow", "Command photo"))
self.PB_Photo_Launch.setText(_translate("MainWindow", "Launch"))
self.PB_Photo_Launch.setToolTip(_translate("MainWindow", "Launch the creation files"))
self.PB_Photo_Reset.setText(_translate("MainWindow", "Reset"))
self.PB_Photo_Reset.setToolTip(_translate("MainWindow", "Refresh alls"))
self.PB_Photo_Quit.setText(_translate("MainWindow", "Return"))
self.PB_Photo_Quit.setToolTip(_translate("MainWindow", "Quit the photo panel"))
def on_RB_Angle_X_clicked(self): # X
# App.Console.PrintMessage("X"+"\n")
pic = QtGui.QPixmap()
pic.loadFromData(base64.b64decode(FCCamera_Axis_rotation_X_BMP))
self.scene = QtWidgets.QGraphicsScene()
self.scene.addPixmap(QtGui.QPixmap(pic))
self.graphicsView.setScene(ui.scene)
def on_RB_Angle_Y_clicked(self): # Y
# App.Console.PrintMessage("Y"+"\n")
pic = QtGui.QPixmap()
pic.loadFromData(base64.b64decode(FCCamera_Axis_rotation_Y_BMP))
self.scene = QtWidgets.QGraphicsScene()
self.scene.addPixmap(QtGui.QPixmap(pic))
self.graphicsView.setScene(ui.scene)
def on_RB_Angle_Z_clicked(self): # Z
pic = QtGui.QPixmap()
pic.loadFromData(base64.b64decode(FCCamera_Axis_rotation_Z_BMP))
self.scene = QtWidgets.QGraphicsScene()
self.scene.addPixmap(QtGui.QPixmap(pic))
self.graphicsView.setScene(ui.scene)
def on_RB_Direction_clicked(self): # D
# App.Console.PrintMessage("D"+"\n")
pic = QtGui.QPixmap()
pic.loadFromData(base64.b64decode(FCCamera_Axis_rotation_D_BMP))
self.scene = QtWidgets.QGraphicsScene()
self.scene.addPixmap(QtGui.QPixmap(pic))
self.graphicsView.setScene(ui.scene)
def on_DS_Angle_valueChanged(self,value): # connection DS_Angle value donnee en degres
global valeur
global numberPhoto
global valueTest
valeur = 0.0
valeur = math.radians(value) # valeur en degres convertie en radian
self.DS_Angle.setStyleSheet("color : Base")
self.label_07.setStyleSheet("color : Base")
try: # section value for angle photo
numberPhoto = 360.0 / value
if abs(float(360.0 / value)) - int(abs(numberPhoto)) != 0.0:
self.PB_Photo_Adjust.setVisible(True)
self.label_08.setVisible(True)
numberPhoto = (abs(360.0 /value))
self.label_07.setStyleSheet("color : Red")
self.PB_Photo_Adjust.setStyleSheet("background-color : #ff0000")
valueTest = abs(int(value))
while ((value + valueTest) < (361 + value)) and ((value - valueTest) < (361 + value)):
if abs(float(360.0 / valueTest)) - int(abs(float(360.0 / valueTest))) == 0.0:
if self.DS_Angle.value() < 0:
self.label_08.setText("Ideal angle : " + str(-valueTest) + " = " + str(abs(int(360.0 / valueTest))) + " images")
else:
self.label_08.setText("Ideal angle : " + str(valueTest) + " = " + str(abs(int(360.0 / valueTest))) + " images")
self.label_08.setStyleSheet("color : #008700")
break
if self.DS_Angle.value() < 0:
valueTest -= 1
else:
valueTest += 1
FreeCADGui.updateGui()
self.PB_Photo_Adjust.setToolTip(u"Click to adjust the number images to 360 degrees" + "\n"
u"detected " + str(numberPhoto) + " = " + str(int(numberPhoto)) + " images" + "\n"
u"ideal choice angle : " + str(valueTest) + " degrees = " + str(abs(int(360.0 / valueTest))) + " images" + "\n" )
else:
numberPhoto = int(abs(360.0 / value))
self.label_07.setStyleSheet("color : Base")
self.label_08.setVisible(False)
self.label_08.setText("")
self.PB_Photo_Adjust.setVisible(False)
self.PB_Photo_Adjust.setStyleSheet("color : Base")
self.PB_Photo_Adjust.setToolTip(u"Adjust the number image to 360 degrees")
except Exception:
numberPhoto = 0
self.PB_Photo.setToolTip(u"Create serial photo for create animation" + "\n"
u"Give the angle rotation desired" + "\n"
u"Number image = 360 / " + str(math.degrees(valeur)) + " = " + str(numberPhoto))
self.label_07.setText("Number image : " + str(numberPhoto))
def on_CB_Multiply_10(self):
if self.CB_Multiply_10.isChecked():
self.DS_Angle.setSingleStep(10.0)
else:
self.DS_Angle.setSingleStep(1.0)
def on_PB_Detect_Camera_clicked(self): # detection Orientation camera
global vertexeS
try:
plan = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()
cam=Gui.ActiveDocument.ActiveView.getCameraNode()
App.Console.PrintMessage("___Camera_Detection_____________________"+"\n")
App.Console.PrintMessage("position : " + str(cam.position.getValue().getValue()) + "\n")
first = FreeCAD.Vector(cam.position.getValue().getValue())
distance_3DView_to_Axis = math.sqrt(first.x*first.x + first.y*first.y + first.z*first.z)
App.Console.PrintMessage(" : (position = Distance Center 3DView to Axis base = " + str(distance_3DView_to_Axis) + ")" + "\n")
App.Console.PrintMessage("orientation : " + str(FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation().Axis)+" , "+str(FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation().Angle) + "\n")
App.Console.PrintMessage("nearDistance : " + str(cam.nearDistance.getValue()) + "\n")
App.Console.PrintMessage("farDistance : " + str(cam.farDistance.getValue()) + "\n")
App.Console.PrintMessage("aspectRatio : " + str(cam.aspectRatio.getValue()) + "\n")
App.Console.PrintMessage("focalDistance : " + str(cam.focalDistance.getValue()) + "\n")
App.Console.PrintMessage("height : " + str(cam.height.getValue()) + "\n" + "\n")
App.Console.PrintMessage("___Camera_Orientation____________________"+"\n")
App.Console.PrintMessage("Radians XYZ Q : " + str(plan)+"\n")
extractValue = datExtract(plan)
xP = float(extractValue[0])
yP = float(extractValue[1])
zP = float(extractValue[2])
qP = float(extractValue[3])
App.Console.PrintMessage("Degrees XYZ : " + str(degrees(xP)) + " , " +str(degrees(yP)) + " , " + str(degrees(zP)) +"\n")
App.Console.PrintMessage("Degrees Q : " + str(degrees(qP)) +"\n"+"\n")
App.Console.PrintMessage("Radians Axis.xyz A : " + str(plan.Axis) + " , " + str(plan.Angle) +"\n")
App.Console.PrintMessage("Degrees Axis.x : " + str(degrees(plan.Axis.x)) +"\n")
App.Console.PrintMessage("Degrees Axis.y : " + str(degrees(plan.Axis.y)) +"\n")
App.Console.PrintMessage("Degrees Axis.z : " + str(degrees(plan.Axis.z)) +"\n")
App.Console.PrintMessage("Degrees Angle : " + str(degrees(plan.Angle)) +"\n")
#http://forum.freecadweb.org/viewtopic.php?f=13&t=14213
App.Console.PrintMessage("Direction : " + str(cam.orientation.getValue().multVec(coin.SbVec3f(0,0,-1)).getValue()) + "\n")
if (vertexeS[0] + vertexeS[1] + vertexeS[2]) != 0.0:
App.Console.PrintMessage("Direction edge : " + str(vertexeS) + "\n")
App.Console.PrintMessage("___FCCamera______________________________"+"\n\n")
App.ActiveDocument.recompute()
except Exception:
App.Console.PrintError("Not Document open" + "\n")
def on_PB_Accept_View_clicked(self): # Accept Rotation Camera to Axis
global valeur
global vertexeS
global ori_Horizont
global ori_Vertical
global bounBoxCenter
if (valeur != 0):
Xv = 0.0; Yv = 0.0; Zv = 0.0
try:
activeView = FreeCADGui.activeDocument().activeView()
cam = Gui.ActiveDocument.ActiveView.getCameraNode()
rot = coin.SbRotation()
if self.RB_Direction.isChecked():
cam.position.setValue(FreeCAD.Vector(bounBoxCenter)) # boundBox edge selected
else:
# activeView.fitAll() # boundBox all center
cam.position.setValue(centerBoundBoxGlobal()) # boundBox all center calculated
#####
if self.RB_Angle_X.isChecked():
Xv = 1.0
App.Console.PrintMessage("(X ")
else:
App.Console.PrintMessage("(- ")
if self.RB_Angle_Y.isChecked():
Yv = 1.0
App.Console.PrintMessage("Y ")
else:
App.Console.PrintMessage("- ")
if self.RB_Angle_Z.isChecked():
Zv = 1.0
App.Console.PrintMessage("Z ")
else:
App.Console.PrintMessage("- ")
if self.RB_Direction.isChecked():
if (vertexeS[0] + vertexeS[1] + vertexeS[2]) != 0.0:
Xv = vertexeS[0]
Yv = vertexeS[1]
Zv = vertexeS[2]
App.Console.PrintMessage("D)" + "\n")
else:
Xv = bounBoxCenter[0]
Yv = bounBoxCenter[1]
Zv = bounBoxCenter[2]
if (Xv + Yv + Zv) == 0.0:
App.Console.PrintMessage("!)" + "\n")
App.Console.PrintError("Not axis selected (edge) for rotation" + "\n"
"or Direction is nul" + "\n")
Gui.updateGui()
else:
App.Console.PrintMessage("-) " + "\n")
#####
rot.setValue(coin.SbVec3f(Xv,Yv,Zv),valeur)
nrot = cam.orientation.getValue() * rot
cam.orientation = nrot
App.Console.PrintMessage(str(valeur)+" rad. , "+str(math.degrees(valeur))+" deg."+"\n")
App.Console.PrintMessage("FCCamera_________________________________"+"\n\n")
except Exception:
App.Console.PrintError("Not Document open"+"\n")
else:
App.Console.PrintError("Value angle egal zero select one Value"+"\n")
self.DS_Angle.setStyleSheet("color : #ff0000")
#### photo ################################################
def SIGNAL_CBox_01_Ecran_Changed(self,text):
global dim_Horizont
global dim_Vertical
global ori_Horizont
global ori_Vertical
if text == "Actual":
dim_Horizont = ori_Horizont
dim_Vertical = ori_Vertical
if text == "Icon 16 x 16":
dim_Horizont = 16
dim_Vertical = 16
elif text == "Icon 32 x 32":
dim_Horizont = 32
dim_Vertical = 32
elif text == "Icon 64 x 64":
dim_Horizont = 64
dim_Vertical = 64
elif text == "Icon 128 x 128":
dim_Horizont = 128
dim_Vertical = 128
elif text == "CGA 320 x 200":
dim_Horizont = 320
dim_Vertical = 200
elif text == "QVGA 320 x 240":
dim_Horizont = 320
dim_Vertical = 240
elif text == "VGA 640 x 480":
dim_Horizont = 640
dim_Vertical = 480
elif text == "SVGA 800 x 600":
dim_Horizont = 800
dim_Vertical = 600
elif text == "XGA 1024 x 768":
dim_Horizont = 1024
dim_Vertical = 768
elif text == "XGA+ 1152 x 864":
dim_Horizont = 1152
dim_Vertical = 864
elif text == "SXGA 1280 x 1024":
dim_Horizont = 1280
dim_Vertical = 1024
elif text == "SXGA+ 1400 x 1050":
dim_Horizont = 1400
dim_Vertical = 1050
elif text == "UXGA 1600 x 1200":
dim_Horizont = 1600
dim_Vertical = 1200
elif text == "QXGA 2048 x 1536":
dim_Horizont = 2048
dim_Vertical = 1536
elif text == "Free":
None
self.DS_01_X.setValue(dim_Horizont)
self.DS_02_Y.setValue(dim_Vertical)
activeView = FreeCADGui.activeDocument().activeView()
mainWindow = FreeCADGui.getMainWindow()
mdi = mainWindow.findChild(QtWidgets.QMdiArea)
mwActive = mdi.activeSubWindow()
mwActive.setGeometry(0, 0, dim_Horizont, dim_Vertical)
def SIGNAL_CBox_02_FileFormat_Changed(self,text):
global formatFichier
if text == "BMP *.bmp":
formatFichier = ".bmp"
elif text == "ICO *.ico":
formatFichier = ".ico"
elif text == "JPEG *.jpeg":
formatFichier = ".jpeg"
elif text == "JPG *.jpg":
formatFichier = ".jpg"
elif text == "PNG *.png":
formatFichier = ".png"
elif text == "PPM *.ppm":
formatFichier = ".ppm"
elif text == "TIF *.tif":
formatFichier = ".tif"
elif text == "TIFF *.tiff":
formatFichier = ".tiff"
elif text == "XBM *.xbm":
formatFichier = ".xbm"
elif text == "XPM *.xpm":
formatFichier = ".xpm"
# elif text == "GIF .gif":
# formatFichier = "*.gif"
def on_DS_01_X_valueChanged(self, value):
global dim_Horizont
global dim_Vertical
dim_Horizont = value
self.DS_01_X.setValue(dim_Horizont)
#self.CBox_01_Ecran.setCurrentIndex(15)
activeView = FreeCADGui.activeDocument().activeView()
mainWindow = FreeCADGui.getMainWindow()
mdi = mainWindow.findChild(QtWidgets.QMdiArea)
mwActive = mdi.activeSubWindow()
mwActive.setGeometry(0, 0, dim_Horizont, dim_Vertical) #
def on_DS_02_Y_valueChanged(self, value):
global dim_Horizont
global dim_Vertical
dim_Vertical = value
self.DS_02_Y.setValue(dim_Vertical)
#self.CBox_01_Ecran.setCurrentIndex(15)
activeView = FreeCADGui.activeDocument().activeView()
mainWindow = FreeCADGui.getMainWindow()
mdi = mainWindow.findChild(QtWidgets.QMdiArea)
mwActive = mdi.activeSubWindow()
mwActive.setGeometry(0, 0, dim_Horizont, dim_Vertical) #
def on_PB_Photo_Launch_clicked(self):
global pathFile
global dim_Horizont
global dim_Vertical
global formatFichier
global valeur
print(formatFichier)
if (valeur != 0):
SaveName, Filter = PySide2.QtWidgets.QFileDialog.getSaveFileName(None, "Save a files ", pathFile, "*" + formatFichier) # PySide
if SaveName == "":
App.Console.PrintMessage("Process aborted" + "\n")
else:
pathFile = SaveName[:SaveName.rfind("/") + 1]
App.Console.PrintMessage("Registration of " + SaveName[:-4] + "_Animate_..." + "\n")
SaveName = SaveName[:-4]
try:
Xv = 0.0;Yv = 0.0;Zv = 0.0
#####
if self.RB_Angle_X.isChecked():
Xv = 1.0
elif self.RB_Angle_Y.isChecked():
Yv = 1.0
elif self.RB_Angle_Z.isChecked():
Zv = 1.0
elif self.RB_Direction.isChecked():
if (vertexeS[0] + vertexeS[1] + vertexeS[2]) != 0.0:
Xv = vertexeS[0]
Yv = vertexeS[1]
Zv = vertexeS[2]
else:
App.Console.PrintError("Not axis selected (edge) for rotation" + "\n"
"or Direction is nul" + "\n")
#####
if (Xv + Yv + Zv) != 0.0:
try:
fileCount = 0
activeView = FreeCADGui.activeDocument().activeView()
cam = Gui.ActiveDocument.ActiveView.getCameraNode()
for i in range(int(360.0 / abs(math.degrees(valeur)))):
Gui.updateGui()
if self.RB_Direction.isChecked():
cam.position.setValue(FreeCAD.Vector(bounBoxCenter)) # boundBox edge selected
else:
# activeView.fitAll() # boundBox all center
cam.position.setValue(centerBoundBoxGlobal()) # boundBox all center calculated
cam = Gui.ActiveDocument.ActiveView.getCameraNode()
rot = coin.SbRotation()
rot.setValue(coin.SbVec3f(Xv,Yv,Zv),valeur)
nrot = cam.orientation.getValue() * rot
cam.orientation = nrot
fileCount += 1
if self.RB_01_Actual.isChecked():
fileName = SaveName + "_Animate_" + '%03d_%03d' % (fileCount, math.degrees(valeur)*fileCount) + "_Cu" + formatFichier
activeView.saveImage(fileName, dim_Horizont, dim_Vertical, "Current")
elif self.RB_02_White.isChecked():
fileName = SaveName + "_Animate_" + '%03d_%03d' % (fileCount, math.degrees(valeur)*fileCount) + "_Wh" + formatFichier
activeView.saveImage(fileName, dim_Horizont, dim_Vertical, "White")
elif self.RB_03_Black.isChecked():
fileName = SaveName + "_Animate_" + '%03d_%03d' % (fileCount, math.degrees(valeur)*fileCount) + "_Bl" + formatFichier
activeView.saveImage(fileName, dim_Horizont, dim_Vertical, "Black")
elif self.RB_04_Transparent.isChecked():
fileName = SaveName + "_Animate_" + '%03d_%03d' % (fileCount, math.degrees(valeur)*fileCount) + "_Tr" + formatFichier
activeView.saveImage(fileName, dim_Horizont, dim_Vertical, "Transparent")
# App.Console.PrintMessage(fileName + "\n")
except Exception:
App.Console.PrintError("Error Creation File"+"\n")
App.Console.PrintMessage("End photos"+"\n")
except Exception: # if error detected to write
App.Console.PrintError("Error write file "+SaveName+"\n") # detect error ... display the text in red (PrintError)
else:
App.Console.PrintError("Give angle value for rotation"+"\n")
App.Console.PrintMessage("(Actual 3Dview = X " + str(dim_Horizont) + ", Y " + str(dim_Vertical) + ") " + "\n")
self.DS_Angle.setStyleSheet("color : #ff0000")
def on_PB_Photo_Adjust_clicked(self):
global valueTest
if self.DS_Angle.value() < 0:
self.DS_Angle.setValue(-valueTest)
else:
self.DS_Angle.setValue(valueTest)
self.PB_Photo_Adjust.setVisible(False)
self.label_08.setVisible(False)
self.label_08.setText("")
# self.label_08.setStyleSheet("color : Base")
def on_PB_Photo_Quit_clicked(self):
global ori_Horizont
global ori_Vertical
self.PB_Photo.setText("Photo")
self.groupBox_00PH.setVisible(False)
self.groupBox_003.setVisible(True)
self.groupBox_004.setVisible(True)
self.groupBox_005.setVisible(True)
# self.CBox_02_FileFormat.setCurrentIndex(4)
# self.CBox_01_Ecran.setCurrentIndex(0)
try:
activeView = FreeCADGui.activeDocument().activeView()
mainWindow = FreeCADGui.getMainWindow()
mdi = mainWindow.findChild(QtWidgets.QMdiArea)
mwActive = mdi.activeSubWindow()
mwActive.setGeometry(0, 0, ori_Horizont, ori_Vertical)
except Exception:
App.Console.PrintError("Not Document open" + "\n")
def on_PB_Photo_Reset_clicked(self): # Reset photo
global ui
ui.on_PB_Reset_clicked()
def on_PB_Photo_clicked(self): # Create photo
global ui
global valeur
global ori_Horizont
global ori_Vertical
global dim_Horizont
global dim_Vertical
global numberPhoto
try:
self.groupBox_003.setVisible(False)
self.groupBox_004.setVisible(False)
self.groupBox_005.setVisible(False)
self.groupBox_00PH.setVisible(True)
self.PB_Photo.setText("Reset")
except Exception:
App.Console.PrintError("Not Document open" + "\n")
#### photo #############################################################
def on_PB_Align_O_To_View_clicked(self): #Align and Fix Object to View
sel = FreeCADGui.Selection.getSelection()
if (len(sel)==0):
App.Console.PrintError("Select one object"+"\n")
else:
Nameelement = sel[0].Name
App.Console.PrintMessage(str(Nameelement)+"\n")
pl = FreeCAD.Placement()
pl.Rotation = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()
pl.Base = sel[0].Placement.Base
App.ActiveDocument.getObject(Nameelement).Placement=pl
def on_PB_Create_Plane_clicked(self): # Create plane
global doc
global positionX # create plans coordinate mouse
global positionY
global positionZ
rayon = 20 # Radius of plane
sel = FreeCADGui.Selection.getSelection()
selEx = FreeCADGui.Selection.getSelectionEx()
objs = [selobj.Object for selobj in selEx]
if len(objs) != 0.0: # radius plane = > BounBox length
s = objs[0].Shape
boundBox_ = s.BoundBox
boundBoxLX = boundBox_.XLength
boundBoxLY = boundBox_.YLength
boundBoxLZ = boundBox_.ZLength
rayon = boundBoxLX
if rayon < boundBoxLY:
rayon = boundBoxLY
elif rayon < boundBoxLZ:
rayon = boundBoxLZ
if self.RB_01_Plane_Point.isChecked(): # Point mouse
None
elif self.RB_02_Plane_Face.isChecked(): # Face, Wire BoundBox Center
positionX = selEx[0].SubObjects[0].BoundBox.Center.x
positionY = selEx[0].SubObjects[0].BoundBox.Center.y
positionZ = selEx[0].SubObjects[0].BoundBox.Center.z
elif self.RB_03_Plane_CMass.isChecked(): # Center O fMass
positionX = sel[0].Shape.CenterOfMass.x
positionY = sel[0].Shape.CenterOfMass.y
positionZ = sel[0].Shape.CenterOfMass.z
elif self.RB_04_Center_BBox.isChecked(): # BoundBox Center
positionX = sel[0].Shape.BoundBox.Center.x
positionY = sel[0].Shape.BoundBox.Center.y
positionZ = sel[0].Shape.BoundBox.Center.z
if len(sel) == 0:
boundBoxLX = rayon
try:
doc = FreeCAD.ActiveDocument
radiusP = rayon # Radius of plane
FcPlane = doc.addObject("App::DocumentObjectGroup","FcPlane")
plan = FreeCADGui.ActiveDocument.ActiveView.getCameraOrientation()
App.Console.PrintMessage("\n"+"Create plane radius : " + str(radiusP) + " mm)"+"\n")
App.Console.PrintMessage("Camera Orientation : " + str(plan)+"\n")
App.Console.PrintMessage("Point position : " + str(positionX)+" "+str(positionY)+" "+str(positionZ)+"\n")
App.Console.PrintMessage("____________________"+"\n")
extractValue = datExtract(plan)
xP = float(extractValue[0])
yP = float(extractValue[1])
zP = float(extractValue[2])
qP = float(extractValue[3])
pl = FreeCAD.Placement()
pl.Rotation.Q = (xP,yP,zP,qP) # rotation of object
pl.Base = FreeCAD.Vector(positionX,positionY,positionZ) # here coordinates XYZ of plan
#create axis
points=[FreeCAD.Vector(0.0,0.0,0.0),FreeCAD.Vector(0.0,0.0,boundBoxLX * 3.0)]
centerX = Draft.makeWire(points,closed=False,face=False,support=None)
centerX.Placement = pl
centerX.Placement.Rotation = centerX.Placement.Rotation.multiply(App.Rotation(0,90,0))
centerX.Placement = centerX.Placement.multiply(App.Placement(App.Vector(0.0,0.0,-float(boundBoxLX * 3.0)/2.0), App.Rotation(App.Vector(0.0,0.0,0.0),0.0), App.Vector(0,0,0)))
centerX.ViewObject.LineColor = (1.0,1.0,1.0)
centerX.ViewObject.LineWidth = 1.0
centerX.ViewObject.DrawStyle = str("Dashdot")
centerX.Label = str("Axis White PlaneX")
FcPlane.addObject(centerX)
points=[FreeCAD.Vector(0.0,0.0,0.0),FreeCAD.Vector(0.0,0.0,boundBoxLX * 3.0)]
centerY = Draft.makeWire(points,closed=False,face=False,support=None)
centerY.Placement = pl
centerY.Placement.Rotation = centerY.Placement.Rotation.multiply(App.Rotation(0,90,90))
centerY.Placement = centerY.Placement.multiply(App.Placement(App.Vector(0.0,0.0,-float(boundBoxLX * 3.0)/2.0), App.Rotation(App.Vector(0.0,0.0,0.0),0.0), App.Vector(0,0,0)))
centerY.ViewObject.LineColor = (1.0,1.0,1.0)
centerY.ViewObject.LineWidth = 1.0
centerY.ViewObject.DrawStyle = str("Dashdot")
centerY.Label = str("Axis White PlaneY")
FcPlane.addObject(centerY)
cercle = Draft.makeCircle(radius=radiusP, placement=pl, face=True, support=None)
Rnameplane = App.ActiveDocument.ActiveObject.Name
App.ActiveDocument.ActiveObject.Label = "PlaneC"
FreeCAD.ActiveDocument.getObject(Rnameplane).MakeFace = True
FreeCADGui.ActiveDocument.getObject(Rnameplane).LineColor = (1.0,0.0,0.0)
FreeCADGui.ActiveDocument.getObject(Rnameplane).ShapeColor = (0.0,0.66666669,1.0)
FreeCADGui.ActiveDocument.getObject(Rnameplane).Transparency = 80
FcPlane.addObject(cercle) # contener character
FreeCAD.ActiveDocument.recompute()
positionX = 0.0
positionY = 0.0
positionZ = 0.0
except Exception:
App.Console.PrintError("Not Document open" + "\n")
def on_PB_To_Face_clicked(self): # view to face selected Face
To_Face_Or_To_Axis(1)
def on_PB_To_Axis_clicked(self): # view to face selected Axis
To_Face_Or_To_Axis(0)
def on_PB_Reset_clicked(self): # Refresh
global valeur
global positionX
global positionY
global positionZ
global vueView
global path
global fileCount
global numberPhoto
global ori_Horizont
global ori_Vertical
try:
Gui.activeDocument().activeView().viewTop()
Gui.SendMsgToActiveView("ViewFit")
valeur = 0.0
fileCount = 0
self.DS_Angle.setProperty("value", 0.0)
positionX = 0.0
positionY = 0.0
positionZ = 0.0
vueView = 0
self.CB_Multiply_10.setChecked(False)
self.DS_Angle.setSingleStep(1.0)
self.RB_Angle_X.setChecked(True)
pic = QtGui.QPixmap()
pic.loadFromData(base64.b64decode(FCCamera_Axis_rotation_X_BMP))
self.scene = QtWidgets.QGraphicsScene()
self.scene.addPixmap(QtGui.QPixmap(pic))
self.graphicsView.setScene(ui.scene)
activeView = FreeCADGui.activeDocument().activeView()
mainWindow = FreeCADGui.getMainWindow()
mdi = mainWindow.findChild(QtWidgets.QMdiArea)
mwActive = mdi.activeSubWindow()
mwActive.setGeometry(0, 0, ori_Horizont, ori_Vertical) #
# self.CBox_01_Ecran.setCurrentIndex(0)
self.DS_01_X.setValue(ori_Horizont)
self.DS_02_Y.setValue(ori_Vertical)
centerBoundBoxGlobal()
self.RB_01_Plane_Point.setChecked(True)
self.RB_01_Actual.setChecked(True)
App.Console.PrintMessage("Refresh (3Dview = X " + str(ori_Horizont) + ", Y " + str(ori_Vertical) + ") " + "\n")
numberPhoto = 0
self.label_07.setText("Number image : " + str(numberPhoto))
except Exception:
App.Console.PrintError("Not Document open" + "\n")
def on_PB_Quit_clicked(self): # quit
global s
global ori_Horizont
global ori_Vertical
global pathFile
global switchVesionMacroSearch
try:
activeView = FreeCADGui.activeDocument().activeView()
mainWindow = FreeCADGui.getMainWindow()
mdi = mainWindow.findChild(QtWidgets.QMdiArea)
mwActive = mdi.activeSubWindow()
mwActive.setGeometry(0, 0, ori_Horizont, ori_Vertical) #
except Exception:
None
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetBool("switchVesionMacroSearch", switchVesionMacroSearch)
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetString("setPathFile", pathFile)#
#FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetInt("CBox_01_Ecran", self.CBox_01_Ecran.currentIndex())#
#FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetInt("CBox_02_FileFormat", self.CBox_02_FileFormat.currentIndex())#
App.Console.PrintMessage("Fin FCCamera" + "\n")
FreeCADGui.Selection.removeObserver(s) # desinstalle la fonction residente
self.window.close()
def on_PB_Help(self): #
import WebGui
WebGui.openBrowser("http://www.freecadweb.org/wiki/index.php?title=Macro_FCCamera")
App.Console.PrintMessage("http://www.freecadweb.org/wiki/index.php?title=Macro_FCCamera" + "\n")
##################################################################################################
#read parameter
pathFile = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetString("setPathFile")
if pathFile == "":
pathFile = path
# CBox_01_Ecran = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetInt("CBox_01_Ecran")#
# print(CBox_01_Ecran)
# CBox_02_FileFormat = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetInt("CBox_02_FileFormat")#
# print(CBox_02_FileFormat)
##################################################################################################
##Start#####
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetString("Version",__version__ + " (" + __date__ + ")")#
#Gui.ActiveDocument.ActiveView.setAxisCross(True) # GuiAxis true
s=SelObserver() # installe the function in resident mode SelObserver
FreeCADGui.Selection.addObserver(s) # installe the function in resident mode SelObserver
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
@mario52a
Copy link
Author

mario52a commented Jan 2, 2016

This macro utility is intended for the use of the program FreeCAD http://www.freecadweb.org/
The icon for your toolbar, it is to place in your macros directory (in the same location of the macro)

toolbar fccamera_00 rename in FCCamera_00.png
fccamera_01 rename in FCCamera_01.png
fccamera_02 rename in FCCamera_02.png
fccamera_03 rename in FCCamera_03.png
fccamera_04 rename in FCCamera_04.png
fccamera_05 rename in FCCamera_05.png
fccamera_06 rename in FCCamera_06.png
fccamera_07 rename in FCCamera_07.png
fccamera_08 rename in FCCamera_08.png

fccamera_axis_rotation_x rename in FCCamera_Axis_rotation_X.png

fccamera_axis_rotation_y rename in FCCamera_Axis_rotation_Y.png

fccamera_axis_rotation_z rename in FCCamera_Axis_rotation_Z.png

fccamera_axis_rotation_d rename in FCCamera_Axis_rotation_D.png

@davidrihtarsic
Copy link

davidrihtarsic commented Jan 17, 2021

Hi, this is a nice macro. I use it for making presentations of assembled constructions. I also add an easy feature that enables animated rotations like this: https://www.youtube.com/watch?v=bybqvos4xYk

...basically, I added:

  • another button for rotation in opposite angle,
  • in function on_PB_Accept_View_clicked added an if with:
if self.CB_Multiply_10.isChecked():
    for n in range(90):
        rot.setValue(coin.SbVec3f(Xv,Yv,Zv),valeur*fw_dir)
        nrot = cam.orientation.getValue() * rot
        cam.orientation = nrot
        FreeCADGui.updateGui()
        time.sleep(0.01)
else:
    rot.setValue(coin.SbVec3f(Xv,Yv,Zv),valeur)
    nrot = cam.orientation.getValue() * rot
    cam.orientation = nrot

Currently, I still have messy code, but if you would be interested in this particular feature I would be happy to contribute and clean the code and make a patch.
Regards,
David

@mario52a
Copy link
Author

mario52a commented Jan 18, 2021

Hi

thank for appreciate my macro and many thanks for this beautiful video, I do not understand well your demand for rotate reverse you must enter one negative angle (10=normal and -10=reverse) or one loop in the principal loop ? why ?

For the animation i just finished (not yet finished example animation in the wiki) my other macro https://wiki.freecadweb.org/Macro_Rotate_To_Point, i adding command for save all coordinates of the object worked (selected rotation translation) you have two possibility:

  1. save the coordinates in a file form [0.0,0.0,0.0],[0.0,0.0,0.0] (i thoughtful for user create his mode and save it in preference)
  2. save in complete macro (saved directly in the macro directory (just accept)) with options include:
  • Type Key Q to Quit

  • Type Key D to Decrease speed

  • Type Key I to Increase speed

  • Type Key P to Pause/Continue or key RETURN or ESCAPE

  • Type Key S to Step by Step (key RETURN or ESCAPE to continue)

  • Type Key M for this message

maybe adding the possibility save also image ... work many objects then work with object name ...

tell me (vous pouvez aussi ma parler en Français)

mario

@davidrihtarsic
Copy link

davidrihtarsic commented Jan 18, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment