Last active
November 19, 2023 10:50
-
-
Save mario52a/262317bc7d8555885b0e to your computer and use it in GitHub Desktop.
This small macro allows you to build a project 3D very easily from a bitmap image 256 levels of gray. I hope that this macro will revolutionize the way of thinking the CAD and CNC any image when what can be converted to object 3D without any intervention. Everything becomes possible regardless of the complexity of the image !
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import unicode_literals | |
""" | |
*************************************************************************** | |
* Copyright (c) 2014 2015 2016 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 General Public License (GPL) * | |
* as published by the Free Software Foundation; either version 3 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 General Public License * | |
* 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) #OS: Ubuntu 20.10 (KDE/plasma) | |
#Word size of OS: 64-bit #Word size of OS: 64-bit | |
#Word size of FreeCAD: 64-bit #Word size of FreeCAD: 64-bit | |
#Version: 0.19.23546 (Git) #Version: 0.19.23578 (Git) | |
#Build type: Release #AppImage Build type: Release | |
#Branch: master #Branch: master | |
#Hash: 6b017f9a16b15b0e628c8d874c4058442dee5548 #Hash: 50c3cbf00579dc4941ca743c25720d016b0453ce | |
#Python version: 3.6.8 #Python version: 3.8.6 | |
#Qt version: 5.12.1 #Qt version: 5.12.5 | |
#Coin version: 4.0.0a #Coin version: 4.0.0 OCC | |
#OCC version: 7.3.0 #version: 7.4.0 | |
#Locale: French/Mars (fr_MA) #Locale: French/Mars (fr_MA) | |
# | |
# pour faire une texture de votre image, l'image doit etre en 256 niveaux de gris (N/B) | |
# une image de 16 millons de couleurs fait l'objet d'une autre procedure d'affichage | |
# http://forum.freecadweb.org/viewtopic.php?f=24&t=5893&sid=c5f8d32c22e1d1a883741b70b1fea2dc | |
# ver 0.7 03/09/2014 PyQt4 and PySide 0.8 16/03/2016 0.9 12/12/2016 0.10 24/12/2016 | |
# ver 0.11 2019/07/03 Py3, ver 0.12 2019/08/04, 0.13 2020/04/17 Layout | |
# ver 0.13b 2020/12/30 try: time.clock() and time.process_time() | |
# ver 0.14 2021/01/06 new2 path name process accept point in path file colored caracter xyz add search upgrade | |
# ver 0.14b 2021/01/ Coordinare and Stretching in TAB for screen 15"; 0.14c add "Gui.SendMsgToActiveView("ViewFit")" | |
# | |
__title__ = "FCTexture" | |
__author__ = "Mario52" | |
__url__ = "https://www.freecadweb.org/" | |
__Wiki__ = "https://wiki.freecadweb.org/Macro_Texture" | |
__version__ = "0.14c" | |
__date__ = "2021/01/16" #YYYY/MM/DD | |
# | |
# | |
import PySide2 | |
from PySide2 import (QtWidgets, QtCore, QtGui) | |
from PySide2.QtWidgets import (QWidget, QApplication, QSlider, QGraphicsView, QGraphicsScene, QVBoxLayout, QStyle) | |
from PySide2.QtGui import * | |
from PySide2.QtCore import * | |
#from PySide2.QtGui import (QPainter, QColor, QIcon) | |
#from PySide2.QtSvg import * | |
#import PySide2.QtXml | |
import WebGui | |
import Draft, Part, FreeCAD, math, PartGui, FreeCADGui, FreeCAD | |
from math import sqrt, pi, sin, cos, asin | |
from FreeCAD import Base | |
Gui = FreeCADGui | |
import Points | |
#import ReverseEngineering | |
import os, time, sys | |
import os.path | |
#### Detect version macro ########################################### | |
global switchVesionMacroSearch#; switchVesionMacroSearch = False | |
try: | |
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 == 0: | |
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetBool("switchVesionMacroSearch", switchVesionMacroSearch) | |
if switchVesionMacroSearch == True: | |
vesionSearch() | |
except Exception: | |
FreeCAD.Console.PrintMessage("Failed to establish a connection" + "\n") | |
#### Detect version macro ########################################### | |
def errorDialog(msg): | |
diag = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical,u"Error Message",msg ) | |
diag.setWindowModality(QtCore.Qt.ApplicationModal) | |
diag.exec_() | |
global verPython ; verPython = sys.version_info.major | |
def decobit(b0 = 0, b1 = 0, b2 = 0, b3 = 0): | |
global verPython | |
if verPython < 3: # Python < 3 | |
b0 = ord(b0) | |
b1 = ord(b1) | |
if b2 == 0: | |
return b0 + (b1*256) | |
else: | |
b2 = ord(b2) | |
b3 = ord(b3) | |
return b0 + (b1*256) + (b2*65536) + (b3*16777216) | |
else: # Python > 3 | |
b0 = int(ord(chr(b0))) | |
b1 = int(ord(chr(b1))) | |
if b2 == 0: | |
return b0 + (b1*256) | |
else: | |
b2 = int(ord(chr(b2))) | |
b3 = int(ord(chr(b3))) | |
return b0 + (b1*256) + (b2*65536) + (b3*16777216) | |
#### Configuration ########################################### | |
global SingleStep ; SingleStep = 1.0 | |
#### Configuration ########################################### | |
global position_X ; position_X = 0.0 | |
global position_Y ; position_Y = 0.0 | |
global position_Z ; position_Z = 0.0 | |
global etirement_X ; etirement_X = 1.0 | |
global etirement_Y ; etirement_Y = 1.0 | |
global etirement_Z ; etirement_Z = 1.0 | |
global modeBrut ; modeBrut = 0 | |
global modeColor ; modeColor = 0 | |
global ecreter ; ecreter = 20 | |
global avecLigne ; avecLigne = 1 | |
global typeligne ; typeligne = 0 | |
global nuance ; nuance = 0 | |
global inversion_X ; inversion_X = 0 | |
global inversion_Y ; inversion_Y = 0 | |
global inversion_Z ; inversion_Z = 0 | |
global plan ; plan = 0 | |
global fond ; fond = 0 | |
global bits_pixel ; bits_pixel = 0 | |
global tailleDonnees; tailleDonnees= 0 | |
global fileCoordasc ; fileCoordasc = 0 | |
global fileCoordpcd ; fileCoordpcd = 0 | |
global ecreterFond ; ecreterFond = 0 | |
global switchContour; switchContour= 0 | |
global valueFilter ; valueFilter = 0 | |
# | |
global pathFile ; pathFile = "" | |
global path | |
#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("\\","/") | |
try: | |
_fromUtf8 = QtCore.QString.fromUtf8 | |
except AttributeError: | |
def _fromUtf8(s): | |
return s | |
class Ui_MainWindow(object): | |
def __init__(self, MainWindow): | |
self.window = MainWindow | |
global path | |
global pathFile | |
global position_X | |
global position_Y | |
global position_Z | |
global etirement_X | |
global etirement_Y | |
global etirement_Z | |
global modeBrut | |
global modeColor | |
global ecreter | |
global typeligne | |
global nuance | |
global avecLigne | |
global inversion_X | |
global inversion_Y | |
global inversion_Z | |
global plan | |
global fond | |
global bits_pixel | |
global tailleDonnees | |
global valueFilter | |
global SingleStep | |
MainWindow.setObjectName(_fromUtf8(__title__)) | |
# MainWindow.resize(300, 600) | |
# MainWindow.setMinimumSize(QtCore.QSize(241, 624)) | |
# MainWindow.setMaximumSize(QtCore.QSize(241, 624)) | |
self.centralWidget = QtWidgets.QWidget(MainWindow) | |
self.groupBox = QtWidgets.QGroupBox() | |
self.groupBox_01 = QtWidgets.QWidget() | |
self.LB_01_Coor_X = QtWidgets.QLabel() | |
self.DS_01_Coor_X = QtWidgets.QDoubleSpinBox() | |
self.DS_01_Coor_X.setDecimals(7) | |
self.DS_01_Coor_X.setMinimum(-9999999.0) | |
self.DS_01_Coor_X.setMaximum(9999999.99) | |
self.DS_01_Coor_X.setSingleStep(SingleStep) | |
self.DS_01_Coor_X.setSuffix(u" mm") | |
self.DS_01_Coor_X.valueChanged.connect(self.on_DS_01_Coor_X_valueChanged) | |
self.LB_02_Coor_Y = QtWidgets.QLabel() | |
self.DS_02_Coor_Y = QtWidgets.QDoubleSpinBox() | |
self.DS_02_Coor_Y.setDecimals(7) | |
self.DS_02_Coor_Y.setMinimum(-9999999.0) | |
self.DS_02_Coor_Y.setMaximum(9999999.99) | |
self.DS_02_Coor_Y.setSingleStep(SingleStep) | |
self.DS_02_Coor_Y.setSuffix(" mm") | |
self.DS_02_Coor_Y.valueChanged.connect(self.on_DS_02_Coor_Y_valueChanged) | |
self.LB_03_Coor_Z = QtWidgets.QLabel() | |
self.DS_03_Coor_Z = QtWidgets.QDoubleSpinBox() | |
self.DS_03_Coor_Z.setDecimals(7) | |
self.DS_03_Coor_Z.setMinimum(-9999999.0) | |
self.DS_03_Coor_Z.setMaximum(9999999.99) | |
self.DS_03_Coor_Z.setSingleStep(SingleStep) | |
self.DS_03_Coor_Z.setSuffix(u" mm") | |
self.DS_03_Coor_Z.valueChanged.connect(self.on_DS_03_Coor_Z_valueChanged) | |
#### | |
self.groupBox_02 = QtWidgets.QWidget() | |
self.LB_01_Stretch_X = QtWidgets.QLabel() | |
self.DS_01_Stretch_X = QtWidgets.QDoubleSpinBox() | |
self.DS_01_Stretch_X.setDecimals(7) | |
self.DS_01_Stretch_X.setMinimum(-9999999.0) | |
self.DS_01_Stretch_X.setMaximum(9999999.99) | |
self.DS_01_Stretch_X.setSingleStep(SingleStep) | |
self.DS_01_Stretch_X.setSuffix(u" mm") | |
self.DS_01_Stretch_X.valueChanged.connect(self.on_DS_01_Stretch_X_valueChanged) | |
self.LB_02_Stretch_Y = QtWidgets.QLabel() | |
self.DS_02_Stretch_Y = QtWidgets.QDoubleSpinBox() | |
self.DS_02_Stretch_Y.setDecimals(7) | |
self.DS_02_Stretch_Y.setMinimum(-9999999.0) | |
self.DS_02_Stretch_Y.setMaximum(9999999.99) | |
self.DS_02_Stretch_Y.setSingleStep(SingleStep) | |
self.DS_02_Stretch_Y.setSuffix(u" mm") | |
self.DS_02_Stretch_Y.valueChanged.connect(self.on_DS_02_Stretch_Y_valueChanged) | |
self.LB_03_Stretch_Z = QtWidgets.QLabel() | |
self.DS_03_Stretch_Z = QtWidgets.QDoubleSpinBox() | |
self.DS_03_Stretch_Z.setDecimals(7) | |
self.DS_03_Stretch_Z.setMinimum(-9999999.0) | |
self.DS_03_Stretch_Z.setMaximum(9999999.99) | |
self.DS_03_Stretch_Z.setSingleStep(SingleStep) | |
self.DS_03_Stretch_Z.setSuffix(u" mm") | |
self.DS_03_Stretch_Z.valueChanged.connect(self.on_DS_03_Stretch_Z_valueChanged) | |
#### | |
self.groupBox_03 = QtWidgets.QGroupBox() | |
self.CB_01_Axis_X = QtWidgets.QCheckBox() | |
self.CB_01_Axis_X.clicked.connect(self.on_CB_01_Axis_X_clicked) | |
self.CB_02_Axis_Y = QtWidgets.QCheckBox() | |
self.CB_02_Axis_Y.clicked.connect(self.on_CB_02_Axis_Y_clicked) | |
self.CB_03_Axis_Z = QtWidgets.QCheckBox() | |
self.CB_03_Axis_Z.clicked.connect(self.on_CB_03_Axis_Z_clicked) | |
#### | |
self.groupBox_04 = QtWidgets.QGroupBox() | |
self.RB_01_Wire = QtWidgets.QRadioButton() | |
self.RB_01_Wire.setChecked(True) | |
self.RB_01_Wire.setIcon(QtGui.QIcon.fromTheme("Draft",QtGui.QIcon(":/icons/Draft_Wire.svg"))) | |
self.RB_01_Wire.clicked.connect(self.on_RB_01_Wire_clicked) | |
self.RB_02_BSpline = QtWidgets.QRadioButton() | |
self.RB_02_BSpline.setIcon(QtGui.QIcon.fromTheme("Draft",QtGui.QIcon(":/icons/Draft_BSpline.svg"))) | |
self.RB_02_BSpline.clicked.connect(self.on_RB_02_BSpline_clicked) | |
self.RB_03_PointsCloud = QtWidgets.QRadioButton() | |
self.RB_03_PointsCloud.setIcon(QtGui.QIcon.fromTheme("Draft",QtGui.QIcon(":/icons/PointsWorkbench.svg"))) | |
self.RB_03_PointsCloud.clicked.connect(self.on_RB_03_PointsCloud_clicked) | |
self.RB_04_Points = QtWidgets.QRadioButton() | |
self.RB_04_Points.setIcon(QtGui.QIcon.fromTheme("Draft",QtGui.QIcon(":/icons/Draft_Point.svg"))) | |
self.RB_04_Points.clicked.connect(self.on_RB_04_Points_clicked) | |
self.CB_01_Nuance = QtWidgets.QCheckBox() | |
self.CB_01_Nuance.setEnabled(False) | |
self.CB_01_Nuance.clicked.connect(self.on_CB_01_Nuance_clicked) | |
#### | |
self.groupBox_05 = QtWidgets.QGroupBox() | |
self.RB_01_Photo = QtWidgets.QRadioButton() | |
self.RB_01_Photo.setChecked(True) | |
self.RB_01_Photo.clicked.connect(self.on_RB_01_Photo_clicked) | |
self.RB_02_PLan = QtWidgets.QRadioButton() | |
self.RB_02_PLan.clicked.connect(self.on_RB_02_PLan_clicked) | |
#### | |
self.groupBox_06 = QtWidgets.QGroupBox() | |
self.CB_01_Pcd = QtWidgets.QCheckBox() | |
self.CB_01_Pcd.clicked.connect(self.on_CB_01_Pcd_clicked) | |
self.CB_02_Asc = QtWidgets.QCheckBox() | |
self.CB_02_Asc.clicked.connect(self.on_CB_02_Asc_clicked) | |
#### | |
self.groupBox_07 = QtWidgets.QGroupBox() | |
# section horizontalSlider | |
self.horizontalSlider = QtWidgets.QSlider() | |
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) | |
self.horizontalSlider.setMaximum(255) | |
self.horizontalSlider.setMinimum(0) | |
self.horizontalSlider.setSliderPosition(0) | |
self.horizontalSlider.setPageStep(1) | |
self.horizontalSlider.setInvertedAppearance(False) | |
self.horizontalSlider.valueChanged.connect(self.on_horizontal_slider) | |
self.SP_01_Height = QtWidgets.QSpinBox() | |
self.SP_01_Height.setMinimum(0) | |
self.SP_01_Height.setMaximum(255) | |
self.SP_01_Height.setValue(0) | |
self.SP_01_Height.setSuffix(u" height") | |
self.SP_01_Height.valueChanged.connect(self.on_SP_01_Height_valueChanged) | |
self.LB_01_Mode_Raw = QtWidgets.QLabel() | |
self.CB_01_Mode_Raw = QtWidgets.QCheckBox() | |
self.CB_01_Mode_Raw.setAutoFillBackground(False) | |
self.CB_01_Mode_Raw.clicked.connect(self.on_CB_01_Mode_Raw_clicked) | |
self.CB_02_Contour = QtWidgets.QCheckBox() | |
self.CB_02_Contour.clicked.connect(self.on_CB_02_Contour_clicked) | |
self.SP_02_Contour = QtWidgets.QSpinBox() | |
self.SP_02_Contour.setMinimum(0) | |
self.SP_02_Contour.setMaximum(20) | |
self.SP_02_Contour.setEnabled(False) | |
self.SP_02_Contour.setValue(0) | |
self.SP_02_Contour.setSuffix(u"/2 Contour") | |
self.SP_02_Contour.valueChanged.connect(self.on_SP_02_Contour_valueChanged) | |
self.LB_03_Capping = QtWidgets.QLabel() | |
self.CB_03_White = QtWidgets.QCheckBox() | |
self.CB_03_White.clicked.connect(self.on_CB_03_White_clicked) | |
self.SP_03_Capping = QtWidgets.QSpinBox() | |
self.SP_03_Capping.setMinimum(0) | |
self.SP_03_Capping.setMaximum(20) | |
self.SP_03_Capping.setValue(20) | |
self.SP_03_Capping.setSuffix(u" Capping") | |
self.SP_03_Capping.valueChanged.connect(self.on_SP_03_Capping_valueChanged) | |
#### | |
self.groupBox_08 = QtWidgets.QGroupBox() | |
self.LB_01_File = QtWidgets.QLabel() | |
self.PBA_progressBar = QtWidgets.QProgressBar() | |
self.PBA_progressBar.setValue(0) | |
self.PBA_progressBar.setVisible(True) | |
self.PBA_progressBar.setOrientation(QtCore.Qt.Horizontal) | |
self.PBA_progressBar.setAlignment(QtCore.Qt.AlignCenter) | |
self.PB_01_File_Launch = QtWidgets.QPushButton() | |
self.PB_01_File_Launch.setIcon(QIcon(QApplication.style().standardIcon(QStyle.SP_DialogOkButton))) | |
self.PB_01_File_Launch.clicked.connect(self.on_PB_01_File_Launch_clicked) # load file | |
self.PB_02_Help = QtWidgets.QPushButton() | |
self.PB_02_Help.setIcon(QIcon(QApplication.style().standardIcon(QStyle.SP_MessageBoxQuestion))) | |
self.PB_02_Help.clicked.connect(self.on_PB_02_Help_clicked) # help | |
self.PB_03_Quit = QtWidgets.QPushButton() | |
self.PB_03_Quit.setIcon(QIcon(QApplication.style().standardIcon(QStyle.SP_DialogCloseButton))) | |
self.PB_03_Quit.clicked.connect(self.on_PB_03_Quit_clicked) # quit | |
#### layout ################################################### | |
self.gridLayout_000 = QtWidgets.QGridLayout(self.centralWidget) | |
self.gridLayout_000.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_00 = QtWidgets.QGridLayout(self.groupBox) | |
self.gridLayout_00.setContentsMargins(10, 10, 10, 10) | |
#### | |
self.tabWidget = QtWidgets.QTabWidget() #Tab | |
#### | |
self.tabWidget.addTab(self.groupBox_01, "Coordinate") | |
self.gridLayout_01 = QtWidgets.QGridLayout(self.groupBox_01) | |
self.gridLayout_01.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_01.addWidget(self.LB_01_Coor_X, 0, 0, 1, 1) | |
self.gridLayout_01.addWidget(self.DS_01_Coor_X, 0, 1, 1, 1) | |
self.gridLayout_01.addWidget(self.LB_02_Coor_Y, 1, 0, 1, 1) | |
self.gridLayout_01.addWidget(self.DS_02_Coor_Y, 1, 1, 1, 1) | |
self.gridLayout_01.addWidget(self.LB_03_Coor_Z, 2, 0, 1, 1) | |
self.gridLayout_01.addWidget(self.DS_03_Coor_Z, 2, 1, 1, 1) | |
#### | |
self.tabWidget.addTab(self.groupBox_02, "Stretching") | |
self.gridLayout_02 = QtWidgets.QGridLayout(self.groupBox_02) | |
self.gridLayout_02.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_02.addWidget(self.LB_01_Stretch_X, 0, 0, 1, 1) | |
self.gridLayout_02.addWidget(self.DS_01_Stretch_X, 0, 1, 1, 1) | |
self.gridLayout_02.addWidget(self.LB_02_Stretch_Y, 1, 0, 1, 1) | |
self.gridLayout_02.addWidget(self.DS_02_Stretch_Y, 1, 1, 1, 1) | |
self.gridLayout_02.addWidget(self.LB_03_Stretch_Z, 2, 0, 1, 1) | |
self.gridLayout_02.addWidget(self.DS_03_Stretch_Z, 2, 1, 1, 1) | |
#### | |
self.gridLayout_00.addWidget(self.tabWidget, 0, 0, 1, 2) | |
#### | |
self.gridLayout_03 = QtWidgets.QGridLayout(self.groupBox_03) | |
self.gridLayout_03.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_03.addWidget(self.CB_01_Axis_X, 0, 0, 1, 1) | |
self.gridLayout_03.addWidget(self.CB_02_Axis_Y, 0, 1, 1, 1) | |
self.gridLayout_03.addWidget(self.CB_03_Axis_Z, 0, 2, 1, 1) | |
self.gridLayout_00.addWidget(self.groupBox_03, 2, 0, 1, 2) | |
#### | |
self.gridLayout_04 = QtWidgets.QGridLayout(self.groupBox_04) | |
self.gridLayout_04.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_04.addWidget(self.RB_01_Wire, 0, 0, 1, 1) | |
self.gridLayout_04.addWidget(self.RB_02_BSpline, 0, 1, 1, 1) | |
self.gridLayout_04.addWidget(self.RB_03_PointsCloud, 0, 2, 1, 1) | |
self.gridLayout_04.addWidget(self.RB_04_Points, 1, 0, 1, 1) | |
self.gridLayout_04.addWidget(self.CB_01_Nuance, 1, 1, 1, 1) | |
self.gridLayout_00.addWidget(self.groupBox_04, 3, 0, 1, 2) | |
#### | |
self.gridLayout_05 = QtWidgets.QGridLayout(self.groupBox_05) | |
self.gridLayout_05.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_05.addWidget(self.RB_01_Photo, 0, 0, 1, 1) | |
self.gridLayout_05.addWidget(self.RB_02_PLan, 0, 1, 1, 1) | |
self.gridLayout_00.addWidget(self.groupBox_05, 4, 0, 1, 1) | |
## | |
self.gridLayout_06 = QtWidgets.QGridLayout(self.groupBox_06) | |
self.gridLayout_06.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_06.addWidget(self.CB_01_Pcd, 0, 0, 1, 1) | |
self.gridLayout_06.addWidget(self.CB_02_Asc, 0, 1, 1, 1) | |
self.gridLayout_00.addWidget(self.groupBox_06, 4, 1, 1, 1) | |
#### | |
self.gridLayout_07 = QtWidgets.QGridLayout(self.groupBox_07) | |
self.gridLayout_07.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_07.addWidget(self.horizontalSlider, 0, 0, 1, 3) | |
self.gridLayout_07.addWidget(self.SP_01_Height, 0, 3, 1, 1) | |
self.gridLayout_07.addWidget(self.LB_01_Mode_Raw, 1, 0, 1, 1) | |
self.gridLayout_07.addWidget(self.CB_01_Mode_Raw, 1, 1, 1, 1) | |
self.gridLayout_07.addWidget(self.CB_02_Contour, 1, 2, 1, 1) | |
self.gridLayout_07.addWidget(self.SP_02_Contour, 1, 3, 1, 1) | |
self.gridLayout_07.addWidget(self.LB_03_Capping, 2, 0, 1, 1) | |
self.gridLayout_07.addWidget(self.CB_03_White, 2, 1, 1, 1) | |
self.gridLayout_07.addWidget(self.SP_03_Capping, 2, 3, 1, 1) | |
self.gridLayout_00.addWidget(self.groupBox_07, 5, 0, 1, 2) | |
#### | |
self.gridLayout_08 = QtWidgets.QGridLayout(self.groupBox_08) | |
self.gridLayout_08.setContentsMargins(10, 10, 10, 10) | |
self.gridLayout_08.addWidget(self.LB_01_File, 0, 0, 1, 3) | |
self.gridLayout_08.addWidget(self.PBA_progressBar, 1, 0, 1, 3) | |
self.gridLayout_08.addWidget(self.PB_01_File_Launch, 2, 0, 1, 1) | |
self.gridLayout_08.addWidget(self.PB_02_Help, 2, 1, 1, 1) | |
self.gridLayout_08.addWidget(self.PB_03_Quit, 2, 2, 1, 1) | |
self.gridLayout_00.addWidget(self.groupBox_08, 6, 0, 1, 2) | |
self.gridLayout_000.addWidget(self.groupBox, 0, 0, 1, 1) | |
#### layout ################################################### | |
MainWindow.setCentralWidget(self.centralWidget) | |
self.retranslateUi(MainWindow) | |
QtCore.QMetaObject.connectSlotsByName(MainWindow) | |
def retranslateUi(self, MainWindow): | |
MainWindow.setWindowTitle(u"FCTexture") | |
MainWindow.setWindowIcon(QtGui.QIcon(path+'FCTexture.png')) | |
MainWindow.setWindowFlags(PySide2.QtCore.Qt.WindowStaysOnTopHint) # PySide2 cette fonction met la fenetre en avant | |
self.groupBox.setTitle(u"ver : " + __version__ + " : " + __date__ + " (rmu)") | |
#### | |
self.DS_01_Coor_X.setToolTip(u"Coordinate placement Axis X.") | |
self.LB_01_Coor_X.setText(u"Coordinate <font color=""#a40000""> <b> X </b> </font> <img src=:/icons/Std_CoordinateSystem.svg height=""18"" width=""18"" align=top>")#middle bottom | |
self.DS_02_Coor_Y.setToolTip(u"Coordinate placement Axis Y.") | |
self.LB_02_Coor_Y.setText(u"Coordinate <font color=""#4e9a06""> <b> Y </b> </font> <img src=:/icons/Std_CoordinateSystem.svg height=""18"" width=""18"" align=top>")#middle bottom | |
self.DS_03_Coor_Z.setToolTip(u"Coordinate placement Axis Z.") | |
self.LB_03_Coor_Z.setText(u"Coordinate <font color=""#204a87""> <b> Z </b> </font> <img src=:/icons/Std_CoordinateSystem.svg height=""18"" width=""18"" align=top>")#middle bottom | |
#### | |
self.DS_01_Stretch_X.setToolTip(u"Stretching Axis X.") | |
self.LB_01_Stretch_X.setText(u"<html> <body> Stretching <font color=""#a40000""> <b> X </b> </font> </body> </html>" ) | |
self.DS_02_Stretch_Y.setToolTip(u"Stretching Axis Y.") | |
self.LB_02_Stretch_Y.setText(u"<html> <body> Stretching <font color=""#4e9a06""> <b> Y </b> </font> </body> </html>" ) | |
self.DS_03_Stretch_Z.setToolTip(u"Stretching Axis Z.") | |
self.LB_03_Stretch_Z.setText(u"<html> <body> Stretching <font color=""#204a87""> <b> Z </b> </font> </body> </html>" ) | |
#### | |
self.groupBox_03.setTitle(u"Inversion") | |
self.CB_01_Axis_X.setText(u"Axis X") | |
self.CB_01_Axis_X.setToolTip(u"Axis X") | |
self.CB_01_Axis_X.setStyleSheet("color : #a40000; font: bold") # couleur du texte et gras | |
self.CB_02_Axis_Y.setText(u"Axis Y") | |
self.CB_02_Axis_Y.setToolTip(u"Axis Y") | |
self.CB_02_Axis_Y.setStyleSheet("color : #4e9a06; font: bold") # couleur du texte et gras | |
self.CB_03_Axis_Z.setText(u"Axis Z") | |
self.CB_03_Axis_Z.setToolTip(u"Axis Z") | |
self.CB_03_Axis_Z.setStyleSheet("color : #204a87; font: bold") # couleur du texte et gras | |
#### | |
self.groupBox_04.setTitle(u"Mode 8 Bits") | |
self.RB_01_Wire.setText(u"Wire") | |
self.RB_01_Wire.setToolTip(u"Make a Wire") | |
self.RB_02_BSpline.setText(u"BSpline") | |
self.RB_02_BSpline.setToolTip(u"Make a BSpline") | |
self.RB_03_PointsCloud.setToolTip(u"Make a Cloud points") | |
self.RB_03_PointsCloud.setText(u"Cloud") | |
self.RB_04_Points.setText(u"Point") | |
self.RB_04_Points.setToolTip(u"Make a Point (the procedure can be long)") | |
self.CB_01_Nuance.setText(u"Nuance") | |
self.CB_01_Nuance.setToolTip(u"To display items in mode photo with shade of gray 20 or 256 shades of gray if Raw mode is set 255") | |
#### | |
self.groupBox_05.setTitle(u"Mode 32 bits") | |
self.RB_01_Photo.setText(u"Photo") | |
self.RB_01_Photo.setToolTip(u"The photo mode is automatically activated when a 32-bit image is detected." + "\n" | |
u"(the procedure can be long)") | |
self.RB_02_PLan.setText(u"Plan") | |
self.RB_02_PLan.setToolTip(u"The plan mode is possible when a 32-bit image and ignore the background of the plan." + "\n" | |
u"(the procedure can be long)") | |
## | |
self.groupBox_06.setTitle(u"File") | |
self.CB_01_Pcd.setText(u".pcd") | |
self.CB_01_Pcd.setToolTip(u"Save the coordinates in file format OriginalName.bmp.pcd" + "\n" | |
u"The function Contour in not availlable with this pcd format" + "\n" | |
u"" | |
u"Version saved : ascii .PCD v0.7") | |
self.CB_02_Asc.setText(u".asc") | |
self.CB_02_Asc.setToolTip(u"Save the coordinates in a file OriginalName.bmp.asc" + "\n" | |
u"The are in format : X Y Z without comma") | |
#### | |
self.groupBox_07.setTitle(u"Capping (10 mm)") | |
self.groupBox_07.setToolTip(u"This function work only with the W/B mode" + "\n" | |
u"The title group give the real height of the shape" + "\n" | |
u"Ex: Capping (10 mm)") | |
self.LB_01_Mode_Raw.setText(u"Raw mode") | |
self.horizontalSlider.setToolTip(u"This function work only with mode Raw 20" + "\n" | |
u"The title group give the real height of the shape" + "\n" | |
u"Ex: 1 to 255") | |
self.CB_01_Mode_Raw.setText("20") | |
self.CB_01_Mode_Raw.setToolTip(u"Raw mode 256 colors or 20 colors") | |
self.LB_03_Capping.setText(u"Capping") | |
self.SP_01_Height.setToolTip(u"This function work only with mode Raw 20" + "\n" | |
u"The title group give the real height of the shape" + "\n" | |
u"Ex: 1 to 255") | |
self.CB_03_White.setText(u"White") | |
self.CB_03_White.setToolTip(u"Capping color White or Black") | |
self.CB_02_Contour.setToolTip(u"Check for activate the Contour SP_03_Capping") | |
self.SP_02_Contour.setToolTip(u"Contour /2 = 1 mm /2 on the height axis Z") | |
self.SP_03_Capping.setToolTip(u"Capping [20 to 0 (white) normal mode] or [255 to 0 (white) Raw mode]") | |
#### | |
self.groupBox_08.setTitle(u"Command") | |
self.LB_01_File.setText(u"File : ") | |
self.LB_01_File.setToolTip(u"Gives informations about the file (Bits_pixel, Size data, Length, Height)") | |
# self.PBA_progressBar.setToolTip(_translate("MainWindow", " ", None)) | |
self.PB_01_File_Launch.setText(u"File and launch") | |
self.PB_01_File_Launch.setToolTip(u"Load the file and launch the process") | |
self.PB_02_Help.setText(u"Help") | |
self.PB_02_Help.setStyleSheet("QToolTip { color: #ffffff; background-color: #204a87; border-color: #ffffff; border-width:2px; border-style:solid; border-radius:0px }"); | |
self.PB_02_Help.setToolTip(u"Display the Wiki page in the FreeCAD browser" + "\n\n" | |
u"For change the parameter disponible: go to Tools > Edit parameter..." + "\n\n" | |
u"__The global step on spinBox :__" + "\n" | |
u"User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__ + " > SingleStep" + "\n" | |
u"Adjust the value desired (1.0 by default)" + "\n\n" | |
u"__For search if the macro is upraded :__" + "\n" | |
u"User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__ + " > switchVesionMacroSearch" + "\n" | |
u"Adjust the switchVesionMacroSearch to True (False by default)" + "\n") | |
self.PB_03_Quit.setText(u"Quit") | |
self.PB_03_Quit.setToolTip(u"Quit FCTexture") | |
def on_DS_01_Coor_X_valueChanged(self,value): | |
global position_X | |
position_X = value | |
def on_DS_02_Coor_Y_valueChanged(self,value): | |
global position_Y | |
position_Y = value | |
def on_DS_03_Coor_Z_valueChanged(self,value): | |
global position_Z | |
position_Z = value | |
def on_DS_01_Stretch_X_valueChanged(self,value): | |
global etirement_X | |
etirement_X = value | |
def on_DS_02_Stretch_Y_valueChanged(self,value): | |
global etirement_Y | |
etirement_Y = value | |
def on_DS_03_Stretch_Z_valueChanged(self,value): | |
global etirement_Z | |
etirement_Z = value | |
def on_horizontal_slider(self, value): | |
global modeBrut | |
global ecreter | |
global valueFilter | |
if modeBrut == 0: | |
valueFilter = float(value) | |
self.SP_01_Height.setValue(value) | |
self.groupBox_07.setTitle("Height ("+str(valueFilter)+" mm)") | |
else: | |
valueFilter = 0.0 | |
self.horizontalSlider.setSliderPosition(0) | |
self.SP_01_Height.setValue(0) | |
def on_SP_01_Height_valueChanged(self, value): | |
global modeBrut | |
global ecreter | |
global valueFilter | |
if modeBrut == 0: | |
valueFilter = float(value) | |
self.horizontalSlider.setValue(value) | |
self.groupBox_07.setTitle("Height ("+str(valueFilter)+" mm)") | |
else: | |
valueFilter = 0.0 | |
self.horizontalSlider.setSliderPosition(0) | |
self.SP_01_Height.setValue(0) | |
def on_CB_01_Mode_Raw_clicked(self): | |
global modeBrut | |
global ecreter | |
global valueFilter | |
valueFilter = 0.0 | |
self.horizontalSlider.setSliderPosition(0) | |
if self.CB_01_Mode_Raw.isChecked(): | |
modeBrut = 1 # if checked mode brut = 255 colors | |
self.SP_03_Capping.setMaximum(255) | |
self.groupBox_07.setTitle("Capping (255 mm)") | |
self.CB_01_Mode_Raw.setText("255") | |
self.SP_02_Contour.setMaximum(255) | |
self.SP_02_Contour.setSuffix(u" Contour") | |
self.SP_02_Contour.setToolTip(u"Contour = 1 mm on the height axis Z") | |
self.SP_01_Height.setEnabled(False) | |
if self.CB_03_White.isChecked(): # if Black | |
self.SP_03_Capping.setValue(0) | |
ecreter = 0 | |
else: | |
self.SP_03_Capping.setValue(255) | |
ecreter = 255 | |
else: | |
modeBrut = 0 # if nochecked White mode brut = 20 colors | |
self.SP_03_Capping.setMaximum(20) | |
self.groupBox_07.setTitle("Capping (10 mm)") | |
self.CB_01_Mode_Raw.setText("20") | |
self.SP_02_Contour.setMaximum(20) | |
self.SP_02_Contour.setSuffix(u"/2 Contour") | |
self.SP_02_Contour.setToolTip(u"Contour /2 = 1 mm /2 on the height axis Z") | |
self.SP_01_Height.setEnabled(True) | |
if self.CB_03_White.isChecked(): # if Black | |
self.SP_03_Capping.setValue(0) | |
ecreter = 0 | |
else: | |
self.SP_03_Capping.setValue(20) # if White | |
ecreter = 20 | |
def on_CB_03_White_clicked(self): # if checked ecreter Black else White | |
global modeColor | |
global ecreter | |
global valueFilter | |
valueFilter = 0.0 | |
self.horizontalSlider.setSliderPosition(0) | |
if self.CB_03_White.isChecked(): | |
modeColor = 1 # if checked mode Black | |
self.CB_03_White.setText("Black") | |
self.SP_03_Capping.setValue(0) | |
else: | |
modeColor = 0 # if nochecked mode White | |
self.CB_03_White.setText("White") | |
if self.CB_01_Mode_Raw.isChecked(): | |
self.SP_03_Capping.setValue(255) | |
self.SP_02_Contour.setSuffix(u" Contour") | |
self.SP_02_Contour.setToolTip(u"Contour = 1 mm on the height axis Z") | |
else: | |
self.SP_03_Capping.setValue(20) | |
self.SP_02_Contour.setSuffix(u"/2 Contour") | |
self.SP_02_Contour.setToolTip(u"Contour /2 = 1 mm /2 on the height axis Z") | |
def on_SP_03_Capping_valueChanged(self,value): # ecreter | |
global ecreter | |
global valueFilter | |
valueFilter = 0.0 | |
self.horizontalSlider.setSliderPosition(0) | |
ecreter = value | |
def on_CB_02_Contour_clicked(self): | |
global switchContour | |
global ecreterFond | |
global valueFilter | |
global fileCoordpcd | |
valueFilter = 0.0 | |
self.horizontalSlider.setSliderPosition(0) | |
self.CB_01_Pcd.setChecked(False) | |
fileCoordpcd = 0 | |
if self.CB_02_Contour.isChecked(): | |
switchContour = 1 | |
self.SP_02_Contour.setEnabled(True) | |
if self.CB_01_Mode_Raw.isChecked(): | |
self.SP_03_Capping.setValue(255) | |
self.SP_02_Contour.setSuffix(u" Contour") | |
self.SP_02_Contour.setToolTip(u"Contour = 1 mm on the height axis Z") | |
else: | |
self.SP_03_Capping.setValue(20) | |
self.SP_02_Contour.setSuffix(u"/2 Contour") | |
self.SP_02_Contour.setToolTip(u"Contour /2 = 1 mm /2 on the height axis Z") | |
else: | |
switchContour = 0 | |
ecreterFond = 0 | |
self.SP_02_Contour.setValue(0) | |
self.SP_02_Contour.setEnabled(False) | |
if self.CB_01_Mode_Raw.isChecked(): | |
self.SP_02_Contour.setSuffix(u" Contour") | |
self.SP_02_Contour.setToolTip(u"Contour = 1 mm on the height axis Z") | |
else: | |
self.SP_02_Contour.setSuffix(u"/2 Contour") | |
self.SP_02_Contour.setToolTip(u"Contour /2 = 1 mm /2 on the height axis Z") | |
def on_SP_02_Contour_valueChanged(self,value): # ecreter Fond | |
global ecreterFond | |
ecreterFond = value | |
def on_RB_04_Points_clicked(self): # if checked then mode point N/B | |
global avecLigne | |
avecLigne = 0 | |
self.CB_01_Nuance.setEnabled(True) | |
self.CB_02_Contour.setEnabled(True) | |
def on_RB_01_Wire_clicked(self): # if checked then 0=makeWire N/B | |
global typeligne | |
global avecLigne | |
typeligne = 0 | |
avecLigne = 1 | |
self.CB_01_Nuance.setChecked(False) | |
self.CB_01_Nuance.setEnabled(False) | |
self.CB_02_Contour.setEnabled(True) | |
def on_RB_02_BSpline_clicked(self): # if no checked then 1=BSpline N/B | |
global typeligne | |
global avecLigne | |
global switchContour | |
global ecreterFond | |
typeligne = 1 | |
avecLigne = 1 | |
switchContour = 0 | |
ecreterFond = 0 | |
self.CB_01_Nuance.setChecked(False) | |
self.CB_01_Nuance.setEnabled(False) | |
self.CB_02_Contour.setEnabled(False) | |
self.CB_02_Contour.setChecked(False) | |
self.SP_02_Contour.setValue(0) | |
self.SP_02_Contour.setEnabled(False) | |
if self.CB_01_Mode_Raw.isChecked(): | |
self.SP_02_Contour.setSuffix(u" Contour") | |
self.SP_02_Contour.setToolTip(u"Contour = 1 mm on the height axis Z") | |
else: | |
self.SP_02_Contour.setSuffix(u"/2 Contour") | |
self.SP_02_Contour.setToolTip(u"Contour /2 = 1 mm /2 on the height axis Z") | |
def on_RB_03_PointsCloud_clicked(self): # Cloud points | |
global typeligne | |
global avecLigne | |
typeligne = 2 | |
ecreterFond = 0 | |
self.CB_01_Nuance.setChecked(False) | |
self.CB_01_Nuance.setEnabled(False) | |
self.CB_02_Contour.setEnabled(True) | |
def on_CB_01_Axis_X_clicked(self): # if checked inverse X | |
global inversion_X | |
if self.CB_01_Axis_X.isChecked(): | |
inversion_X = 1 | |
else: | |
inversion_X = 0 | |
def on_CB_02_Axis_Y_clicked(self): # if checked inverse Y | |
global inversion_Y | |
if self.CB_02_Axis_Y.isChecked(): | |
inversion_Y = 1 | |
else: | |
inversion_Y = 0 | |
def on_CB_03_Axis_Z_clicked(self): # if checked inverse Z | |
global inversion_Z | |
if self.CB_03_Axis_Z.isChecked(): | |
inversion_Z = 1 | |
else: | |
inversion_Z = 0 | |
def on_RB_01_Photo_clicked(self): # if checked then Photo colors | |
global plan | |
plan = 0 | |
def on_RB_02_PLan_clicked(self): # if checked then Plan colors | |
global plan | |
global modeBrut | |
global ecreter | |
plan = 1 | |
modeBrut = 1 # if checked mode brut = 255 colors | |
ecreter = 255 | |
self.SP_03_Capping.setMaximum(255) | |
self.SP_03_Capping.setValue(255) | |
self.CB_03_White.setText("White") | |
self.CB_01_Mode_Raw.setText("255") | |
self.CB_01_Mode_Raw.setChecked(True) | |
def on_CB_01_Nuance_clicked(self): # if checked fond Black else White | |
global nuance | |
if self.CB_01_Nuance.isChecked(): | |
nuance = 1 # if checked Nuance ok | |
else: | |
nuance = 0 # if nochecked Nuance Ko | |
def on_PB_03_Quit_clicked(self): | |
FreeCAD.Console.PrintMessage("End FCTexture"+"\n") | |
self.window.hide() | |
def on_PB_02_Help_clicked(self): | |
WebGui.openBrowser("https://wiki.freecadweb.org/Macro_FCTexture") | |
App.Console.PrintMessage("https://wiki.freecadweb.org/Macro_FCTexture" + "\n") | |
def on_CB_01_Pcd_clicked(self): # pcd | |
global fileCoordpcd | |
if self.CB_02_Contour.isChecked(): | |
self.CB_01_Pcd.setChecked(False) | |
else: | |
if self.CB_01_Pcd.isChecked(): | |
fileCoordpcd = 1 # if checked file pcd ok | |
else: | |
fileCoordpcd = 0 # if nochecked file pcd Ko | |
def on_CB_02_Asc_clicked(self): # Asc | |
global fileCoordasc | |
if self.CB_02_Asc.isChecked(): | |
fileCoordasc = 1 # if checked file asc ok | |
else: | |
fileCoordasc = 0 # if nochecked file asc Ko | |
def on_PB_01_File_Launch_clicked(self): | |
global path | |
global pathFile | |
global position_X | |
global position_Y | |
global position_Z | |
global etirement_X | |
global etirement_Y | |
global etirement_Z | |
global modeBrut | |
global modeColor | |
global ecreter | |
global typeligne | |
global avecLigne | |
global inversion_X | |
global inversion_Y | |
global inversion_Z | |
global plan | |
global fond | |
global bits_pixel | |
global tailleDonnees | |
global fileCoordasc | |
global fileCoordpcd | |
global ecreterFond | |
global switchContour | |
global valueFilter | |
# Configuration FCTexture | |
# FreeCAD.Console.PrintMessage("position_X : "+str(position_X)+"\n") | |
# FreeCAD.Console.PrintMessage("position_Y : "+str(position_Y)+"\n") | |
# FreeCAD.Console.PrintMessage("position_Z : "+str(position_Z)+"\n") | |
# FreeCAD.Console.PrintMessage("etirement_X : "+str(etirement_X)+"\n") | |
# FreeCAD.Console.PrintMessage("etirement_Y : "+str(etirement_Y)+"\n") | |
# FreeCAD.Console.PrintMessage("etirement_Z : "+str(etirement_Z)+"\n") | |
# FreeCAD.Console.PrintMessage("ecreter : "+str(ecreter)+"\n") | |
# FreeCAD.Console.PrintMessage("wire : "+str(avecLigne)+"\n") | |
# FreeCAD.Console.PrintMessage("typeligne : "+str(typeligne)+"\n") | |
# FreeCAD.Console.PrintMessage("point : "+str(avecLigne)+"\n") | |
# FreeCAD.Console.PrintMessage("inversion_X : "+str(inversion_X)+"\n") | |
# FreeCAD.Console.PrintMessage("inversion_Y : "+str(inversion_Y)+"\n") | |
# FreeCAD.Console.PrintMessage("inversion_Z : "+str(inversion_Z)+"\n") | |
# FreeCAD.Console.PrintMessage("plan : "+str(plan)+"\n") | |
# FreeCAD.Console.PrintMessage("fond : "+str(fond)+"\n") | |
doc = FreeCAD.ActiveDocument | |
if doc == None: | |
doc = FreeCAD.newDocument() | |
self.PB_01_File_Launch.setStyleSheet("background-color: QPalette.Base") # origin system | |
self.LB_01_File.setText("File :") | |
OpenName = "" | |
OpenName, Filter = PySide2.QtWidgets.QFileDialog.getOpenFileName(None, "Read an image file", pathFile, "*.bmp")# PySide2 | |
try: | |
if OpenName != "": | |
SaveName = OpenName | |
####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 | |
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/FCTexture").SetString("Path",pathFile) | |
####new | |
OpenName = SaveNameformatFichier | |
try: | |
depart = time.clock() | |
except Exception: | |
try: | |
depart = time.process_time() | |
except Exception: None | |
FreeCAD.Console.PrintMessage("Read the file "+OpenName+"\n") | |
f = open(OpenName, "rb") | |
length = os.path.getsize(OpenName) | |
# decode header file | |
bytes = f.read(2)# Signature du fichier. BM=Bitmap windows, BA= Bitmap | |
# FreeCAD.Console.PrintMessage(str(bytes[0]) + str(bytes[1])+"\n") | |
bytes = f.read(4)# Taille totale du fichier en octets | |
bytes = f.read(4)# Champ reserve | |
bytes = f.read(4)# Adresse de la zone de definition de l image | |
adresse = decobit(bytes[0],bytes[1],bytes[2],bytes[3]) | |
# FreeCAD.Console.PrintMessage(str(adresse)+" adresse "+"\n") | |
bytes = f.read(4)# Taille en octets de l'en-tete BITMAPINFOHEADER | |
entete = decobit(bytes[0],bytes[1],bytes[2],bytes[3]) | |
# FreeCAD.Console.PrintMessage(str(entete)+" entete "+"\n") | |
bytes = f.read(4)# Largeur de l image en pixels | |
Largeur = decobit(bytes[0],bytes[1],bytes[2],bytes[3]) | |
# FreeCAD.Console.PrintMessage(str(Largeur)+" Largeur "+"\n") | |
bytes = f.read(4)# Hauteur de l image en pixels | |
hauteur = decobit(bytes[0],bytes[1],bytes[2],bytes[3]) | |
# FreeCAD.Console.PrintMessage(str(hauteur)+" hauteur "+"\n") | |
bytes = f.read(2)# Nombre de plans | |
plans = decobit(bytes[0],bytes[1]) | |
# FreeCAD.Console.PrintMessage(str(plans)+" plans "+"\n") | |
bytes = f.read(2)# Nombre de bits par pixel | |
bits_pixel = decobit(bytes[0],bytes[1]) | |
FreeCAD.Console.PrintMessage(str(bits_pixel)+" bits_pixel "+"\n") | |
bytes = f.read(4)# Type de compression : 0=pas de compression,1=compresse a 8 bits par pixel, 2=4bits par pixel. | |
bytes = f.read(4)# Taille en octets des donnees de l image | |
tailleDonnees = decobit(bytes[0],bytes[1],bytes[2],bytes[3]) | |
# FreeCAD.Console.PrintMessage(str(tailleDonnees)+" tailleDonnees "+"\n") | |
bytes = f.read(4)# Resolution horizontale en pixels par metre | |
bytes = f.read(4)# Resolution verticale en pixels par metre | |
bytes = f.read(4)# Nombre de couleurs dans l image : 0=maximum possible. Si une palette est utilisee, ce nombre indique le nombre de couleurs de la palette | |
couleurs = decobit(bytes[0],bytes[1],bytes[2],bytes[3]) | |
# FreeCAD.Console.PrintMessage(str(couleurs)+" couleurs "+"\n") | |
bytes = f.read(4)# Nombre de couleurs importantes. 0= toutes importantes | |
self.LB_01_File.setText("File: "+str(bits_pixel)+":bits " +str(tailleDonnees)+":data ("+str(Largeur)+" x "+str(hauteur)+")") | |
Gui.updateGui() # rafraichi l'ecran | |
f.seek(adresse, 0) # seek(position, 0=defaut 1=a la position courante 2=a partir de la fin du fichier) | |
coor_X = 0.0 | |
coor_Y = 0.0 | |
coor_Z = 0.0 | |
###########256 couleurs debut##################################### | |
if couleurs == 256: | |
completion = Largeur % 4 | |
ii = 0 | |
pnts = [] | |
points = [] | |
pointsCloud = [] | |
del pnts[:] | |
del points[:] | |
del pointsCloud[:] | |
import Points | |
pointsCloud = Points.Points() | |
## contourLineG = [] # ligne du bord gauche | |
## del contourLineG[:] # ligne du bord gauche | |
## contourLineD = [] # ligne du bord droit | |
## del contourLineD[:] # ligne du bord droit | |
self.PBA_progressBar.setMaximum(tailleDonnees) | |
for Y in range(tailleDonnees): | |
self.PBA_progressBar.setValue(Y) | |
ii += 1 | |
try: | |
bytes = ord(f.read(1)) | |
pnts.append(str(bytes)) | |
except: | |
None | |
try: | |
if ((ii % Largeur) == 0) and (completion > 0): | |
if completion == 3: | |
bytes = (f.read(1)) | |
Y += 1 | |
elif completion == 2: | |
bytes = (f.read(2)) | |
Y += 2 | |
elif completion == 1: | |
bytes = (f.read(3)) | |
Y += 3 | |
ii = 0 | |
except: | |
None | |
f.close() | |
ii = 0 | |
####################################################################### pour asc | |
if fileCoordasc != 0: | |
mypath = OpenName + ".asc" | |
file_asc = open(mypath,"w") # save coordinates OpenName.asc | |
####################################################################### pour pcd | |
# .PCD v.7 - Point Cloud Data file format # http://pointclouds.org/documentation/tutorials/pcd_file_format.php | |
# for save PCD format # | |
if fileCoordpcd != 0: | |
mypath = OpenName + ".pcd" | |
file_pcd = open(mypath,"w") # save coordinates OpenName.pcd # pour fichier PCD | |
file_pcd.write("# .PCD v0.7 - Point Cloud Data file format" + "\n") # .PCD v0.7 - Point Cloud Data file format | |
file_pcd.write("VERSION .7" + "\n") # VERSION 0.7 | |
file_pcd.write("FIELDS x y z rgb" + "\n") # FIELDS x y z rgb | |
file_pcd.write("SIZE 4 4 4 4"+"\n") # SIZE 4 | |
file_pcd.write("TYPE F F F F"+"\n") # F F F F | |
file_pcd.write("COUNT 1 1 1 1"+"\n") # COUNT 1 1 1 1 | |
file_pcd.write("WIDTH " + str(Largeur) + "\n") # WIDTH 640 | |
file_pcd.write("HEIGHT " + str(hauteur) + "\n") # HEIGHT 480 | |
file_pcd.write("VIEWPOINT 0 0 0 1 0 0 0" + "\n") # VIEWPOINT 0 0 0 1 0 0 0 | |
file_pcd.write("POINTS " + str( Largeur * hauteur) + "\n") # POINTS 307200 | |
file_pcd.write("DATA ascii" + "\n") # DATA ascii | |
####################################################################### pour pcd | |
if modeBrut == 0: | |
ecreterFond = self.SP_02_Contour.value() | |
ecreterFond = (float(ecreterFond)/2) | |
self.SP_02_Contour.setSuffix(u"/2 Contour") | |
else: | |
ecreterFond = self.SP_02_Contour.value() | |
self.SP_02_Contour.setSuffix(u" Contour") | |
if switchContour == 0: | |
ecreterFond = 1000 | |
if self.CB_03_Axis_Z.isChecked(): | |
ecreterFond = (-ecreterFond) | |
self.PBA_progressBar.setMaximum(hauteur) | |
for Y in range(hauteur): | |
self.PBA_progressBar.setValue(Y) | |
## switchLine = 0 # switch lignes bords gauche droit | |
for X in range(Largeur): | |
if X > Largeur: | |
del points[:] | |
else: | |
if modeBrut == 0: | |
if float(pnts[ii]) > 247: # 20 Filter | |
pnts[ii] = "10" | |
elif float(pnts[ii]) > 234: # 19 | |
pnts[ii] = "9.5" | |
elif float(pnts[ii]) > 221: # 18 | |
pnts[ii] = "9" | |
elif float(pnts[ii]) > 208: # 17 | |
pnts[ii] = "8.5" | |
elif float(pnts[ii]) > 195: # 16 | |
pnts[ii] = "8" | |
elif float(pnts[ii]) > 182: # 15 | |
pnts[ii] = "7.5" | |
elif float(pnts[ii]) > 169: # 14 | |
pnts[ii] = "7" | |
elif float(pnts[ii]) > 156: # 13 | |
pnts[ii] = "6.5" | |
elif float(pnts[ii]) > 143: # 12 | |
pnts[ii] = "6" | |
elif float(pnts[ii]) > 130: # 11 | |
pnts[ii] = "5.5" | |
elif float(pnts[ii]) > 117: # 10 | |
pnts[ii] = "5" | |
elif float(pnts[ii]) > 104: # 9 | |
pnts[ii] = "4.5" | |
elif float(pnts[ii]) > 91: # 8 | |
pnts[ii] = "4" | |
elif float(pnts[ii]) > 78: # 7 | |
pnts[ii] = "3.5" | |
elif float(pnts[ii]) > 65: # 6 | |
pnts[ii] = "3" | |
elif float(pnts[ii]) > 52: # 5 | |
pnts[ii] = "2.5" | |
elif float(pnts[ii]) > 39: # 4 | |
pnts[ii] = "2" | |
elif float(pnts[ii]) > 26: # 3 | |
pnts[ii] = "1.5" | |
elif float(pnts[ii]) > 13: # 2 | |
pnts[ii] = "1" | |
elif float(pnts[ii]) > 1: # 1 | |
pnts[ii] = "0.5" | |
else : | |
pnts[ii] = "0" # 0 | |
if modeBrut == 0: # ecreter 20 colors | |
if modeColor == 0: | |
if float(pnts[ii]) > ((ecreter + 1) / 2): # ecreter White | |
pnts[ii] = str((ecreter + 1) / 2) | |
else: | |
if float(pnts[ii]) < ((ecreter + 1) / 2): # ecreter Black | |
pnts[ii] = str((ecreter + 1) / 2) | |
else: # ecreter 255 colors | |
if modeColor == 0: | |
if float(pnts[ii]) > ecreter: # ecreter White | |
pnts[ii] = str(ecreter) | |
else: | |
if float(pnts[ii]) < ecreter: # ecreter Black | |
pnts[ii] = str(ecreter) | |
if (valueFilter != 0.0) and (modeBrut == 0): | |
pnts[ii] = str( float(pnts[ii]) * (valueFilter/10.0)) | |
coor_X = (X * etirement_X) + position_X | |
coor_Y = (Y * etirement_Y) + position_Y | |
coor_Z = (float(pnts[ii]) * etirement_Z) + position_Z | |
if inversion_X > 0: | |
coor_X = (-coor_X) | |
if inversion_Y > 0: | |
coor_Y = (-coor_Y) | |
if inversion_Z > 0: | |
coor_Z = (-coor_Z) | |
if (coor_Z != ecreterFond): # ici pour contour | |
try: | |
if typeligne == 2: # 2=cloud | |
pointsCloud.addPoints([FreeCAD.Vector(coor_X,coor_Y,coor_Z)]) | |
points += [FreeCAD.Vector(coor_X,coor_Y,coor_Z)] # (pour remplir) | |
if avecLigne == 1: # 1=Ligne 0=point 2=cloud | |
points += [FreeCAD.Vector(coor_X,coor_Y,coor_Z)] | |
elif avecLigne == 0: # 0=point | |
if nuance == 1: # 1 = nuance | |
a = Draft.makePoint(coor_X,coor_Y,coor_Z) | |
FreeCADGui.activeDocument().getObject(a.Label).PointColor = (coor_Z*0.00392157,coor_Z*0.00392157,coor_Z*0.00392157) | |
else: | |
Draft.makePoint(coor_X,coor_Y,coor_Z) | |
################################################################### pour asc | |
if fileCoordasc != 0: | |
file_asc.write(str(coor_X)+" "+str(coor_Y)+" "+str(coor_Z)+"\n") | |
################################################################### pour pcd | |
if fileCoordpcd != 0: | |
pcdColor = 0.0 #(pcdColor_r) + (pcdColor_v*256) + (pcdColor_b*65536) # pour un champ | |
file_pcd.write(str(coor_X) + " " + str(coor_Y) + " " + str(coor_Z) + " " + str(pcdColor)+"\n") # | |
################################################################### pour pcd | |
except: | |
try: | |
file_asc.close() # essais if error detected to write ... or not the file is closed | |
except Exception: | |
None | |
FreeCAD.Console.PrintError("Not ActiveDocument detected "+"\n")# errorDialog("Not ActiveDocument detected") | |
break | |
elif (len(points) > 0): | |
if ((avecLigne == 1) and (len(points) != 0)) or (typeligne == 2): | |
###cree la ligne jusque la base############################### | |
if points[0].z != 0.0: | |
points.insert(0,points[0]) | |
points[0].z = 0.0 | |
pointsCloud.addPoints([points[0]]) | |
if points[-1].z != 0.0: | |
points.append(FreeCAD.Vector(points[-1].x,points[-1].y,points[-1].z)) | |
points[-1].z = 0.0 | |
pointsCloud.addPoints([points[-1]]) | |
###cree la ligne jusque la base############################### | |
if (points[0] != points[-1]): | |
if (typeligne == 0): # 0=makeWire | |
Draft.makeWire(points,closed=False,face=False,support=None) | |
elif typeligne == 1: | |
Draft.makeBSpline(points,closed=False) # 1=makeBSpline | |
## if switchLine == 0: # ligne du bord gauche droit | |
## switchLine = 1 # ligne du bord gauche droit | |
## contourLineG.append(points[0]) # ligne du bord gauche | |
## contourLineD.append(points[-1]) # ligne du bord droit | |
del points[:] | |
ii += 1 | |
try: | |
if (avecLigne == 1) and (len(points) != 0) and (typeligne != 2): | |
## if switchLine == 0: # ligne du bord gauche droit | |
## switchLine = 1 # ligne du bord gauche droit | |
## contourLineG.append(points[0]) # ligne du bord gauche | |
## contourLineD.append(points[-1]) # ligne du bord droit | |
if typeligne == 0: # 0=makeWire | |
Draft.makeWire(points,closed=False,face=False,support=None) | |
else: | |
Draft.makeBSpline(points,closed=False) # 1=makeBSpline | |
except: | |
FreeCAD.Console.PrintError("Not ActiveDocument detected "+"\n") #errorDialog("Not ActiveDocument detected") | |
break | |
del points[:] | |
## Draft.makeWire(contourLineG,closed=False,face=False,support=None) # ligne du bord gauche | |
## del contourLineG[:] # ligne du bord gauche | |
## Draft.makeWire(contourLineD,closed=False,face=False,support=None) # ligne du bord droit | |
## del contourLineD[:] # ligne du bord droit | |
if typeligne == 2: | |
Points.show(pointsCloud) | |
#### Create nurbs surface##################################### | |
# import ReverseEngineering as Reen | |
# create an approximating nurbs surface with smoothing algorithm | |
# s = Reen.approxSurface(Points=pointsCloud, UDegree=4, VDegree=4, NbUPoles=16, NbVPoles=16, Smooth=True, Weight=0.1, Grad=0.5,Bend=0.2, Iterations=5, Correction=True, PatchFactor=1.2) | |
# Part.show(s.toShape()) | |
# App.ActiveDocument.recompute() | |
# create an approximating nurbs surface with smoothing algorithm | |
# #### Create Mesh ############################################# | |
#http://forum.freecadweb.org/viewtopic.php?f=13&t=12796&start=10 | |
# import ReverseEngineering as Reen | |
# mesh=Reen.triangulate(pointsCloud, 10000, 8.0) | |
# import Mesh | |
# Mesh.show(mesh) | |
if fileCoordasc != 0: | |
file_asc.close() # pour asc | |
if fileCoordpcd != 0: | |
file_pcd.close() # pour pcd | |
if (valueFilter != 0.0): | |
# global ui # appel | |
ff = ui | |
ff.on_CB_01_Mode_Raw_clicked() | |
valueFilter = 0 | |
##256 couleurs fin##################################### | |
# | |
###########16 millions couleurs debut########################### | |
elif bits_pixel == 32: #if couleurs == 0: # 16 millions couleurs pour 32 bits mode 1 bit | |
if adresse == 138: # mode 2 bits | |
bytes = (f.read(1)) | |
completion = Largeur % 4 | |
ii = 0 | |
ic = 0 | |
r_color = 0.0 | |
v_color = 0.0 | |
b_color = 0.0 | |
pnts = [] | |
points = [] | |
del pnts[:] | |
del points[:] | |
self.PBA_progressBar.setMaximum(tailleDonnees) | |
for Y in range(tailleDonnees): | |
self.PBA_progressBar.setValue(Y) | |
ii = 0 | |
for ic in range(3): | |
ii += 1 | |
try: | |
bytes = ord(f.read(1)) | |
pnts.append(str(bytes)) | |
except: | |
None | |
f.read(1) | |
ii += 1 | |
try: | |
if ((ii % Largeur) == 0) and (completion > 0): | |
if completion == 3: | |
bytes = ord(f.read(1)) | |
Y += 1 | |
elif completion == 2: | |
bytes = ord(f.read(2)) | |
Y += 2 | |
elif completion == 1: | |
bytes = ord(f.read(3)) | |
Y += 3 | |
except: | |
None | |
f.close() | |
ii = 0 | |
self.PBA_progressBar.setMaximum(hauteur) | |
if fileCoordasc != 0: | |
mypath = OpenName + ".asc" | |
file_asc = open(mypath,"w") # save coordinates OpenName.asc | |
####################################################################### pour pcd | |
# .PCD v.7 - Point Cloud Data file format | |
# for save PCD format # | |
if fileCoordpcd != 0: | |
mypath = OpenName + ".pcd" | |
file_pcd = open(mypath,"w") # save coordinates OpenName.pcd # pour fichier PCD #http://pointclouds.org/documentation/tutorials/pcd_file_format.php | |
file_pcd.write("# .PCD v0.7 - Point Cloud Data file format" + "\n") # .PCD v0.7 - Point Cloud Data file format | |
file_pcd.write("VERSION .7" + "\n") # VERSION 0.7 | |
file_pcd.write("FIELDS x y z rgb" + "\n") # FIELDS x y z rgb | |
file_pcd.write("SIZE 4 4 4 4"+"\n") # SIZE 4 | |
file_pcd.write("TYPE F F F F"+"\n") # F F F F | |
file_pcd.write("COUNT 1 1 1 1"+"\n") # COUNT 1 1 1 1 | |
file_pcd.write("WIDTH " + str(Largeur) + "\n") # WIDTH 640 | |
file_pcd.write("HEIGHT " + str(hauteur) + "\n") # HEIGHT 480 | |
file_pcd.write("VIEWPOINT 0 0 0 1 0 0 0" + "\n") # VIEWPOINT 0 0 0 1 0 0 0 | |
file_pcd.write("POINTS " + str( Largeur * hauteur) + "\n") # POINTS 307200 | |
file_pcd.write("DATA ascii" + "\n") # DATA ascii | |
####################################################################### pour pcd | |
for Y in range(hauteur): | |
self.PBA_progressBar.setValue(Y) | |
for X in range(Largeur): | |
if X > Largeur: | |
del points[:] | |
else: | |
coor_X = (X * etirement_X) + position_X | |
coor_Y = (Y * etirement_Y) + position_Y | |
coor_Z = ( etirement_Z) + position_Z | |
if inversion_X > 0: | |
coor_X = (-coor_X) | |
if inversion_Y > 0: | |
coor_Y = (-coor_Y) | |
if inversion_Z > 0: | |
coor_Z = (-coor_Z) | |
b_color = float(pnts[ii])*0.00392157 ; pcdColor_b = int(pnts[ii])*65536 # a partir du ";" encodage pour PCD | |
ii += 1 | |
v_color = float(pnts[ii])*0.00392157 ; pcdColor_v = int(pnts[ii])*256 # a partir du ";" encodage pour PCD | |
ii += 1 | |
r_color = float(pnts[ii])*0.00392157 ; pcdColor_r = int(pnts[ii]) # a partir du ";" encodage pour PCD | |
ii += 1 | |
try: | |
if plan == 0: # 0=Photo | |
a = Draft.makePoint(coor_X,coor_Y,coor_Z) # ok pour 32 bits mode | |
FreeCADGui.activeDocument().getObject(a.Label).PointColor = (r_color,v_color,b_color) | |
else: # 1=Plan | |
if modeColor == 0: # white background | |
if (r_color < (ecreter*0.00392157)) and (r_color < (ecreter*0.00392157)) and (r_color < (ecreter*0.00392157)): # ecreter White | |
a = Draft.makePoint(coor_X,coor_Y,coor_Z) | |
FreeCADGui.activeDocument().getObject(a.Label).PointColor = (r_color,v_color,b_color) | |
else: # black background | |
if (r_color > (ecreter*0.00392157)) and (r_color > (ecreter*0.00392157)) and (r_color > (ecreter*0.00392157)): # ecreter Black | |
a = Draft.makePoint(coor_X,coor_Y,coor_Z) | |
FreeCADGui.activeDocument().getObject(a.Label).PointColor = (r_color,v_color,b_color) | |
################################################################### pour asc | |
if fileCoordasc != 0: | |
file_asc.write(str(coor_X)+" "+str(coor_Y)+" "+str(coor_Z)+"\n") | |
################################################################### pour pcd | |
if fileCoordpcd != 0: | |
pcdColor = (pcdColor_r) + (pcdColor_v*256) + (pcdColor_b*65536) # pour un champ (pas teste avec FreeCAD) | |
file_pcd.write(str(coor_X) + " " + str(coor_Y) + " " + str(coor_Z) + " " + str(pcdColor)+"\n") # | |
################################################################### pour pcd | |
except: | |
try: | |
file_asc.close() | |
except Exception: | |
None | |
FreeCAD.Console.PrintError("Not ActiveDocument detected "+"\n") | |
break | |
del points[:] | |
if fileCoordasc != 0: | |
try: | |
file_asc.close() # pour asc | |
except Exception: | |
None | |
if fileCoordpcd != 0: | |
try: | |
file_pcd.close() # pour pcd | |
except Exception: | |
None | |
###########16 millions couleurs fin##################################### | |
else: | |
FreeCAD.Console.PrintError("Bits_pixel "+str(bits_pixel)+" unrecognized format"+"\n") | |
FreeCAD.Console.PrintWarning("Wait i recompute :"+"\n") | |
Gui.updateGui() # rafraichi l'ecran | |
App.ActiveDocument.recompute() | |
self.PB_01_File_Launch.setStyleSheet("background-color: green") # This function gives a color button | |
try: | |
arrivee = time.clock() | |
FreeCAD.Console.PrintMessage("Time : "+str("%.2f" % ((arrivee - depart)/60))+" min"+"\n") | |
except Exception: | |
try: | |
arrivee = time.process_time() | |
FreeCAD.Console.PrintMessage("Time : "+str("%.2f" % ((arrivee - depart)/60))+" min"+"\n") | |
except Exception: None | |
Gui.SendMsgToActiveView("ViewFit") | |
FreeCAD.Console.PrintMessage("_End Work_____________"+"\n") | |
except: | |
self.PB_01_File_Launch.setStyleSheet("background-color: red") # This function gives a color button | |
FreeCAD.Console.PrintMessage("Error in reading the file "+OpenName+"\n") | |
errorDialog(u"Error in reading the file "+OpenName) | |
self.PBA_progressBar.setValue(0) | |
#read parameter | |
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetString("Version",__version__ + " (" + __date__ + ")")# | |
pathFile = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/FCTexture").GetString("Path") | |
if pathFile == "": | |
pathFile = path | |
#write parameter | |
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros" + __title__).SetString("Path",pathFile) | |
#### | |
SingleStepC = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).GetFloat("SingleStep") | |
if SingleStepC == 0: | |
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macros/FCMmacros/" + __title__).SetFloat("SingleStep",SingleStep) | |
else: | |
SingleStep = SingleStepC | |
################################################################################################## | |
MainWindow = QtWidgets.QMainWindow() | |
ui = Ui_MainWindow(MainWindow) | |
MainWindow.show() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi
thanks for report this error,
can you share please a small image Grayscale 8-bit bitmaps saved by Photoshop ex: 200 x 200 (+/-)
thanks
mario