FreeCAD-library/PartsLibrary.FCMacro

232 lines
9.6 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#***************************************************************************
#* *
#* Copyright (c) 2013 Yorik van Havre <yorik@uncreated.net> *
#* *
#* 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. *
#* *
#* This program 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 program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
__title__="FreeCAD Parts Library Macro"
__author__ = "Yorik van Havre"
__url__ = "http://www.freecadweb.org"
'''
FreeCAD Parts Library import macro
INSTALLATION
This script is made to be used as a FreeCAD macro, and to be placed
inside your macros folder (default is $HOME/.FreeCAD on mac/linux,
C:/Users/youruser/Application Data/FreeCAD on windows).
After it is installed on the above location, it will be available
in the macros menu. On first run, it will ask you for the location
of your library.
USAGE
This macro adds a browser window to the FreeCAD interface, from
which you can browse and install items from the library.
'''
import FreeCAD, FreeCADGui, Part, zipfile, tempfile, Mesh, os, subprocess
from PySide import QtGui, QtCore
param = FreeCAD.ParamGet('User parameter:Plugins/partlib')
s=param.GetString('destination')
print('User parameter:Plugins/partlib : destination : ',s)
if s<>'':
LIBRARYPATH = s
else:
folderDialog = QtGui.QFileDialog.getExistingDirectory(None,u"Choose folder library")
param.SetString('destination',folderDialog)
s=param.GetString('destination')
LIBRARYPATH = s
global ExpFileSystemModel
class ExpFileSystemModel(QtGui.QFileSystemModel):
"a custom QFileSystemModel that displays freecad file icons"
def __init__(self):
QtGui.QFileSystemModel.__init__(self)
def data(self, index, role):
if index.column() == 0 and role == QtCore.Qt.DecorationRole:
if index.data().lower().endswith('.fcstd'):
return QtGui.QIcon(':icons/freecad-doc.png')
return super(ExpFileSystemModel, self).data(index, role)
class ExpDockWidget(QtGui.QDockWidget):
"a library explorer dock widget"
def __init__(self,LIBRARYPATH):
QtGui.QDockWidget.__init__(self)
self.setObjectName("PartsLibrary")
self.setWindowTitle("Parts Library")
# setting up a directory model that shows only fcstd and step
self.dirmodel = ExpFileSystemModel()
self.dirmodel.setRootPath(LIBRARYPATH)
self.dirmodel.setNameFilters(["*.fcstd","*.FcStd","*.FCSTD","*.stp","*.STP","*.step","*.STEP", "*.brp", "*.BRP", "*.brep", "*.BREP"])
self.dirmodel.setNameFilterDisables(0)
folder = QtGui.QTreeView()
folder.setModel(self.dirmodel)
folder.clicked[QtCore.QModelIndex].connect(self.clicked)
folder.doubleClicked[QtCore.QModelIndex].connect(self.doubleclicked)
# Don't show columns for size, file type, and last modified
folder.setHeaderHidden(True)
folder.hideColumn(1)
folder.hideColumn(2)
folder.hideColumn(3)
folder.setRootIndex(self.dirmodel.index(LIBRARYPATH))
self.preview = QtGui.QLabel()
self.preview.setFixedHeight(128)
formatLabel = QtGui.QLabel("Add to library")
savebutton = QtGui.QPushButton("Save")
icon = QtGui.QIcon.fromTheme("document-save")
savebutton.setIcon(icon)
savebutton.clicked.connect(self.addtolibrary)
pushbutton = QtGui.QPushButton("Push")
icon = QtGui.QIcon.fromTheme("document-export")
pushbutton.setIcon(icon)
pushbutton.clicked.connect(self.pushlibrary)
fcstdCB = QtGui.QCheckBox('FCStd')
fcstdCB.setCheckState(QtCore.Qt.Checked)
fcstdCB.setEnabled(False)
self.stepCB = QtGui.QCheckBox('STEP')
self.stepCB.setCheckState(QtCore.Qt.Checked)
self.stlCB = QtGui.QCheckBox('STL')
self.stlCB.setCheckState(QtCore.Qt.Checked)
container = QtGui.QWidget()
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(folder,0,0,1,3)
grid.addWidget(self.preview,1,0,5,1)
grid.addWidget(formatLabel,1,1,1,2)
grid.addWidget(fcstdCB,2,1,1,2)
grid.addWidget(self.stepCB,3,1,1,2)
grid.addWidget(self.stlCB,4,1,1,2)
grid.addWidget(savebutton,5,1,1,1)
grid.addWidget(pushbutton,5,2,1,1)
container.setLayout(grid)
self.setWidget(container)
def clicked(self, index):
path = self.dirmodel.filePath(index)
if path.lower().endswith(".fcstd"):
zfile=zipfile.ZipFile(path)
files=zfile.namelist()
# check for meta-file if it's really a FreeCAD document
if files[0] == "Document.xml":
image="thumbnails/Thumbnail.png"
if image in files:
image=zfile.read(image)
thumbfile = tempfile.mkstemp(suffix='.png')[1]
thumb = open(thumbfile,"wb")
thumb.write(image)
thumb.close()
im = QtGui.QPixmap(thumbfile)
self.preview.setPixmap(im)
return
self.preview.clear()
def doubleclicked(self, index):
path = self.dirmodel.filePath(index)
if path.lower().endswith(".stp") or path.lower().endswith(".step") or path.lower().endswith(".brp") or path.lower().endswith(".brep"):
Part.show(Part.read(path))
elif path.lower().endswith(".fcstd"):
FreeCADGui.ActiveDocument.mergeProject(path)
FreeCADGui.SendMsgToActiveView("ViewFit")
def addtolibrary(self):
fileDialog = QtGui.QFileDialog.getSaveFileName(None,u"Choose category and set a filename without extension", LIBRARYPATH)
if fileDialog != '':
#filename = fileDialog[0].split("/")[-1]
#if filename.split(".")[-1].lowercase == "fcstd" or "stl
FCfilename = fileDialog[0] + ".fcstd"
FreeCAD.ActiveDocument.saveCopy(FCfilename)
if self.stepCB.isChecked() or self.stlCB.isChecked():
toexport = []
objs = FreeCAD.ActiveDocument.Objects
for obj in objs :
if obj.ViewObject.Visibility == True :
toexport.append(obj)
if self.stepCB.isChecked() :
STEPfilename = fileDialog[0] + ".step"
Part.export(toexport,STEPfilename)
if self.stlCB.isChecked() :
STLfilename = fileDialog[0] + ".stl"
Mesh.export(toexport,STLfilename)
def pushlibrary(self):
try:
import git
except:
FreeCAD.Console.PrintError("The Python Git module was not found. Please install the python-git package.\n")
return
try:
repo = git.Repo(LIBRARYPATH)
except:
FreeCAD.Console.PrintError("Your library is not a valid Git repository. Please fork/clone it first.\n")
return
pushOK = True
if not repo.remotes:
FreeCAD.Console.PrintWarning("Arch","Warning: no remote repository set. Unable to push")
pushOK = False
modified_files = repo.git.diff("--name-only").split()
untracked_files = repo.git.ls_files("--other","--exclude-standard").split()
import ArchServer
d = ArchServer._ArchGitDialog()
if not pushOK:
d.checkBox.setChecked(False)
d.checkBox.setEnabled(False)
d.label.setText(str(len(modified_files)+len(untracked_files))+" new and modified file(s)")
d.lineEdit.setText("Changed " + str(modified_files))
d.checkBox.hide()
d.radioButton.hide()
d.radioButton_2.hide()
r = d.exec_()
if r:
for o in modified_files + untracked_files:
repo.git.add(o)
repo.git.commit(m=d.lineEdit.text())
if d.checkBox.isChecked():
repo.git.push()
if QtCore.QDir(LIBRARYPATH).exists():
m = FreeCADGui.getMainWindow()
w = m.findChild(QtGui.QDockWidget,"PartsLibrary")
if w:
if w.isVisible():
w.hide()
else:
w.show()
else:
m.addDockWidget(QtCore.Qt.RightDockWidgetArea,ExpDockWidget(LIBRARYPATH))
else:
print "Library path ", LIBRARYPATH, "not found."
print "Please set the correct path to your Parts library in the macro script"