Compare commits

...

24 Commits

Author SHA1 Message Date
wmayer dbb4cc6415 replace insecure use of eval() with proper use of units 2019-05-11 13:02:55 +02:00
wmayer e25cd6c71b py3/py2: use exec as function 2019-05-10 19:26:12 +02:00
Yorik van Havre 1fb7ed43cf Arch: Fixed error in roof - Fixes #3864 2019-05-07 22:49:19 -03:00
Yorik van Havre ebca0c9836 Draft: Fixed 0.18.1 bug in DXF importer 2019-05-02 16:10:12 -03:00
wmayer 476b4d5f97 Py3 fix: correctly convert a Python str to const char* 2019-04-21 10:15:13 +02:00
wmayer 3450cf9860 Py3: fix reading/writing from/to OBJ file 2019-04-21 10:14:45 +02:00
wmayer 0dc75267fe fixes 0003913: libspnav crash on linux wayland during startup 2019-04-05 17:43:53 +02:00
Bernd Hahnebach f7dccfaa90 FEM: ccx tools, set back the assignment of linux and osx ccx binary path 2019-04-04 15:42:43 +02:00
lorenz 76542ae729 FEM: osx: try to fix default ccx detection 2019-04-04 15:42:24 +02:00
wmayer 55698377f9 fix crash when checking an empty error message of an exception 2019-04-04 15:37:55 +02:00
wmayer f21cbce8cd fix crash when checking an empty error message of an exception 2019-04-04 15:37:40 +02:00
Bernd Hahnebach 9152703516 FEM: Py3 fix in result reader 2019-04-04 15:37:25 +02:00
Peter Eszlari c264c76d8f Linux/appdata: generate release info 2019-04-04 15:37:09 +02:00
sliptonic d8f5560cac Path: per Werner, fixing bug for function removed from string module
in py3
2019-04-04 15:36:53 +02:00
wmayer 442e411cf0 Py3: make string concatenation to work with Py2 and Py3 2019-04-04 15:36:39 +02:00
wmayer 55080952a8 reset expressions of a property when removing it 2019-04-04 15:36:25 +02:00
wmayer f185504b4e in case object deletion fails then make sure to re-enable updates of the main window 2019-04-04 15:36:11 +02:00
wmayer 2bc3daedcc Document::breakDependency should handle exceptions to avoid to leave document in an inconsistent state 2019-04-04 15:35:57 +02:00
Craig Marshall 2cef63f8a3 Fix #2034 with more precision attempt 2 2019-04-04 15:35:43 +02:00
triplus 81a7d937bd Fix for build failure on Ubuntu 16.04 2019-04-04 15:35:12 +02:00
wmayer 64f3424cab fix mouse selection for high DPI screens 2019-04-04 15:33:10 +02:00
wmayer 64cb745ddc fixes 0003130: FreeCAD 0.17 Qt5 bugs with external display 2019-04-04 15:32:54 +02:00
wmayer 228876f8f2 improve drawing of overlay pixmaps for high DPI screens 2019-04-04 15:32:34 +02:00
Yorik van Havre 8ece48c70b Arch: Fixed materials not updating their dicts 2019-03-20 10:01:27 -03:00
23 changed files with 242 additions and 135 deletions
+7 -1
View File
@@ -3031,7 +3031,13 @@ void Document::breakDependency(DocumentObject* pcObject, bool clear)
std::vector<App::ObjectIdentifier> paths; std::vector<App::ObjectIdentifier> paths;
pcObject->ExpressionEngine.getPathsToDocumentObject(it->second, paths); pcObject->ExpressionEngine.getPathsToDocumentObject(it->second, paths);
for (std::vector<App::ObjectIdentifier>::iterator jt = paths.begin(); jt != paths.end(); ++jt) { for (std::vector<App::ObjectIdentifier>::iterator jt = paths.begin(); jt != paths.end(); ++jt) {
pcObject->ExpressionEngine.setValue(*jt, nullptr); // When nullifying the expression handle case where an identifier lacks of the property
try {
pcObject->ExpressionEngine.setValue(*jt, nullptr);
}
catch (const Base::Exception& e) {
e.ReportException();
}
} }
} }
} }
+20 -3
View File
@@ -496,10 +496,27 @@ void DocumentObject::setDocument(App::Document* doc)
onSettingDocument(); onSettingDocument();
} }
void DocumentObject::onAboutToRemoveProperty(const char* prop) void DocumentObject::onAboutToRemoveProperty(const char* name)
{ {
if (_pDoc) if (_pDoc) {
_pDoc->removePropertyOfObject(this, prop); _pDoc->removePropertyOfObject(this, name);
Property* prop = getDynamicPropertyByName(name);
if (prop) {
auto expressions = ExpressionEngine.getExpressions();
std::vector<App::ObjectIdentifier> removeExpr;
for (auto it : expressions) {
if (it.first.getProperty() == prop) {
removeExpr.push_back(it.first);
}
}
for (auto it : removeExpr) {
ExpressionEngine.setValue(it, boost::shared_ptr<Expression>());
}
}
}
} }
void DocumentObject::onBeforeChange(const Property* prop) void DocumentObject::onBeforeChange(const Property* prop)
+4 -3
View File
@@ -1062,6 +1062,7 @@ boost::any ObjectIdentifier::getValue() const
destructor d1(pyvalue); destructor d1(pyvalue);
Base::PyGILStateLocker locker;
if (!pyvalue) if (!pyvalue)
throw Base::RuntimeError("Failed to get property value."); throw Base::RuntimeError("Failed to get property value.");
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
@@ -1078,12 +1079,12 @@ boost::any ObjectIdentifier::getValue() const
return boost::any(PyString_AsString(pyvalue)); return boost::any(PyString_AsString(pyvalue));
#endif #endif
else if (PyUnicode_Check(pyvalue)) { else if (PyUnicode_Check(pyvalue)) {
#if PY_MAJOR_VERSION >= 3
return boost::any(PyUnicode_AsUTF8(pyvalue));
#else
PyObject * s = PyUnicode_AsUTF8String(pyvalue); PyObject * s = PyUnicode_AsUTF8String(pyvalue);
destructor d2(s); destructor d2(s);
#if PY_MAJOR_VERSION >= 3
return boost::any(PyUnicode_AsUTF8(s));
#else
return boost::any(PyString_AsString(s)); return boost::any(PyString_AsString(s));
#endif #endif
} }
+6 -4
View File
@@ -354,13 +354,15 @@ void InterpreterSingleton::runInteractiveString(const char *sCmd)
PyErr_Fetch(&errobj, &errdata, &errtraceback); PyErr_Fetch(&errobj, &errdata, &errtraceback);
RuntimeError exc(""); // do not use PyException since this clears the error indicator RuntimeError exc(""); // do not use PyException since this clears the error indicator
if (errdata) {
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
if (PyUnicode_Check(errdata)) if (PyUnicode_Check(errdata))
exc.setMessage(PyUnicode_AsUTF8(errdata)); exc.setMessage(PyUnicode_AsUTF8(errdata));
#else #else
if (PyString_Check(errdata)) if (PyString_Check(errdata))
exc.setMessage(PyString_AsString(errdata)); exc.setMessage(PyString_AsString(errdata));
#endif #endif
}
PyErr_Restore(errobj, errdata, errtraceback); PyErr_Restore(errobj, errdata, errtraceback);
if (PyErr_Occurred()) if (PyErr_Occurred())
PyErr_Print(); PyErr_Print();
+11 -4
View File
@@ -571,20 +571,27 @@ QPixmap BitmapFactoryInst::merge(const QPixmap& p1, const QPixmap& p2, Position
{ {
// does the similar as the method above except that this method does not resize the resulting pixmap // does the similar as the method above except that this method does not resize the resulting pixmap
int x = 0, y = 0; int x = 0, y = 0;
#if QT_VERSION >= 0x050000
qreal dpr1 = p1.devicePixelRatio();
qreal dpr2 = p2.devicePixelRatio();
#else
qreal dpr1 = 1;
qreal dpr2 = 1;
#endif
switch (pos) switch (pos)
{ {
case TopLeft: case TopLeft:
break; break;
case TopRight: case TopRight:
x = p1.width () - p2.width (); x = p1.width ()/dpr1 - p2.width ()/dpr2;
break; break;
case BottomLeft: case BottomLeft:
y = p1.height() - p2.height(); y = p1.height()/dpr1 - p2.height()/dpr2;
break; break;
case BottomRight: case BottomRight:
x = p1.width () - p2.width (); x = p1.width ()/dpr1 - p2.width ()/dpr2;
y = p1.height() - p2.height(); y = p1.height()/dpr1 - p2.height()/dpr2;
break; break;
} }
+24 -12
View File
@@ -1092,9 +1092,15 @@ void StdCmdDelete::activated(int iMsg)
// handle the view provider // handle the view provider
Gui::getMainWindow()->setUpdatesEnabled(false); Gui::getMainWindow()->setUpdatesEnabled(false);
(*it)->openTransaction("Delete"); try {
vpedit->onDelete(ft->getSubNames()); (*it)->openTransaction("Delete");
(*it)->commitTransaction(); vpedit->onDelete(ft->getSubNames());
(*it)->commitTransaction();
}
catch (const Base::Exception& e) {
(*it)->abortTransaction();
e.ReportException();
}
Gui::getMainWindow()->setUpdatesEnabled(true); Gui::getMainWindow()->setUpdatesEnabled(true);
Gui::getMainWindow()->update(); Gui::getMainWindow()->update();
@@ -1171,18 +1177,24 @@ void StdCmdDelete::activated(int iMsg)
if (autoDeletion) { if (autoDeletion) {
Gui::getMainWindow()->setUpdatesEnabled(false); Gui::getMainWindow()->setUpdatesEnabled(false);
(*it)->openTransaction("Delete"); try {
for (std::vector<Gui::SelectionObject>::iterator ft = sel.begin(); ft != sel.end(); ++ft) { (*it)->openTransaction("Delete");
Gui::ViewProvider* vp = pGuiDoc->getViewProvider(ft->getObject()); for (std::vector<Gui::SelectionObject>::iterator ft = sel.begin(); ft != sel.end(); ++ft) {
if (vp) { Gui::ViewProvider* vp = pGuiDoc->getViewProvider(ft->getObject());
// ask the ViewProvider if it wants to do some clean up if (vp) {
if (vp->onDelete(ft->getSubNames())) { // ask the ViewProvider if it wants to do some clean up
doCommand(Doc,"App.getDocument(\"%s\").removeObject(\"%s\")" if (vp->onDelete(ft->getSubNames())) {
,(*it)->getName(), ft->getFeatName()); doCommand(Doc,"App.getDocument(\"%s\").removeObject(\"%s\")"
,(*it)->getName(), ft->getFeatName());
}
} }
} }
(*it)->commitTransaction();
}
catch (const Base::Exception& e) {
(*it)->abortTransaction();
e.ReportException();
} }
(*it)->commitTransaction();
Gui::getMainWindow()->setUpdatesEnabled(true); Gui::getMainWindow()->setUpdatesEnabled(true);
Gui::getMainWindow()->update(); Gui::getMainWindow()->update();
@@ -98,6 +98,12 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
mainWindow = window; mainWindow = window;
#if defined(Q_OS_LINUX) && defined(SPNAV_FOUND) #if defined(Q_OS_LINUX) && defined(SPNAV_FOUND)
#if QT_VERSION >= 0x050200
if (!QX11Info::isPlatformX11()) {
Base::Console().Log("Application is not running on X11\n");
return;
}
#endif
if (spnav_x11_open(QX11Info::display(), window->winId()) == -1) { if (spnav_x11_open(QX11Info::display(), window->winId()) == -1) {
Base::Console().Log("Couldn't connect to spacenav daemon\n"); Base::Console().Log("Couldn't connect to spacenav daemon\n");
} else { } else {
+18
View File
@@ -390,7 +390,16 @@ int PolyPickerSelection::locationEvent(const SoLocation2Event* const, const QPoi
if (polyline.isWorking()) { if (polyline.isWorking()) {
// check the position // check the position
#if QT_VERSION >= 0x050600
qreal dpr = _pcView3D->getGLWidget()->devicePixelRatioF();
#else
qreal dpr = 1.0;
#endif
QRect r = _pcView3D->getGLWidget()->rect(); QRect r = _pcView3D->getGLWidget()->rect();
if (dpr != 1.0) {
r.setHeight(r.height()*dpr);
r.setWidth(r.width()*dpr);
}
if (!r.contains(clPoint)) { if (!r.contains(clPoint)) {
if (clPoint.x() < r.left()) if (clPoint.x() < r.left())
@@ -599,7 +608,16 @@ int FreehandSelection::locationEvent(const SoLocation2Event* const e, const QPoi
if (polyline.isWorking()) { if (polyline.isWorking()) {
// check the position // check the position
#if QT_VERSION >= 0x050600
qreal dpr = _pcView3D->getGLWidget()->devicePixelRatioF();
#else
qreal dpr = 1.0;
#endif
QRect r = _pcView3D->getGLWidget()->rect(); QRect r = _pcView3D->getGLWidget()->rect();
if (dpr != 1.0) {
r.setHeight(r.height()*dpr);
r.setWidth(r.width()*dpr);
}
if (!r.contains(clPoint)) { if (!r.contains(clPoint)) {
if (clPoint.x() < r.left()) if (clPoint.x() < r.left())
+2 -2
View File
@@ -116,7 +116,7 @@ QByteArray PythonOnlineHelp::loadResource(const QString& filename) const
dict = PyDict_Copy(dict); dict = PyDict_Copy(dict);
QByteArray cmd = QByteArray cmd =
"import string, os, sys, pydoc, pkgutil\n" "import os, sys, pydoc, pkgutil\n"
"\n" "\n"
"class FreeCADDoc(pydoc.HTMLDoc):\n" "class FreeCADDoc(pydoc.HTMLDoc):\n"
" def index(self, dir, shadowed=None):\n" " def index(self, dir, shadowed=None):\n"
@@ -160,7 +160,7 @@ QByteArray PythonOnlineHelp::loadResource(const QString& filename) const
" ret = pydoc.html.index(dir, seen)\n" " ret = pydoc.html.index(dir, seen)\n"
" if ret != None:\n" " if ret != None:\n"
" indices.append(ret)\n" " indices.append(ret)\n"
"contents = heading + string.join(indices) + '''<p align=right>\n" "contents = heading + ' '.join(indices) + '''<p align=right>\n"
"<font color=\"#909090\" face=\"helvetica, arial\"><strong>\n" "<font color=\"#909090\" face=\"helvetica, arial\"><strong>\n"
"pydoc</strong> by Ka-Ping Yee &lt;ping@lfw.org&gt;</font>'''\n" "pydoc</strong> by Ka-Ping Yee &lt;ping@lfw.org&gt;</font>'''\n"
"htmldocument=pydoc.html.page(title,contents)\n"; "htmldocument=pydoc.html.page(title,contents)\n";
+2 -1
View File
@@ -323,7 +323,8 @@ void InteractiveInterpreter::runCode(PyCodeObject* code) const
if (PyErr_Occurred()) { /* get latest python exception information */ if (PyErr_Occurred()) { /* get latest python exception information */
PyObject *errobj, *errdata, *errtraceback; PyObject *errobj, *errdata, *errtraceback;
PyErr_Fetch(&errobj, &errdata, &errtraceback); PyErr_Fetch(&errobj, &errdata, &errtraceback);
if (PyDict_Check(errdata)) { // the error message can be empty so errdata will be null
if (errdata && PyDict_Check(errdata)) {
PyObject* value = PyDict_GetItemString(errdata, "swhat"); PyObject* value = PyDict_GetItemString(errdata, "swhat");
if (value) { if (value) {
Base::RuntimeError e; Base::RuntimeError e;
+10 -4
View File
@@ -680,7 +680,10 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
str << "import pyside2uic\n" str << "import pyside2uic\n"
<< "from PySide2 import QtCore, QtGui, QtWidgets\n" << "from PySide2 import QtCore, QtGui, QtWidgets\n"
<< "import xml.etree.ElementTree as xml\n" << "import xml.etree.ElementTree as xml\n"
<< "from cStringIO import StringIO\n" << "try:\n"
<< " from cStringIO import StringIO\n"
<< "except:\n"
<< " from io import StringIO\n"
<< "\n" << "\n"
<< "uiFile = \"" << file.c_str() << "\"\n" << "uiFile = \"" << file.c_str() << "\"\n"
<< "parsed = xml.parse(uiFile)\n" << "parsed = xml.parse(uiFile)\n"
@@ -691,7 +694,7 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
<< " frame = {}\n" << " frame = {}\n"
<< " pyside2uic.compileUi(f, o, indent=0)\n" << " pyside2uic.compileUi(f, o, indent=0)\n"
<< " pyc = compile(o.getvalue(), '<string>', 'exec')\n" << " pyc = compile(o.getvalue(), '<string>', 'exec')\n"
<< " exec pyc in frame\n" << " exec(pyc, frame)\n"
<< " #Fetch the base_class and form class based on their type in the xml from designer\n" << " #Fetch the base_class and form class based on their type in the xml from designer\n"
<< " form_class = frame['Ui_%s'%form_class]\n" << " form_class = frame['Ui_%s'%form_class]\n"
<< " base_class = eval('QtWidgets.%s'%widget_class)\n"; << " base_class = eval('QtWidgets.%s'%widget_class)\n";
@@ -699,7 +702,10 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
str << "import pysideuic\n" str << "import pysideuic\n"
<< "from PySide import QtCore, QtGui\n" << "from PySide import QtCore, QtGui\n"
<< "import xml.etree.ElementTree as xml\n" << "import xml.etree.ElementTree as xml\n"
<< "from cStringIO import StringIO\n" << "try:\n"
<< " from cStringIO import StringIO\n"
<< "except:\n"
<< " from io import StringIO\n"
<< "\n" << "\n"
<< "uiFile = \"" << file.c_str() << "\"\n" << "uiFile = \"" << file.c_str() << "\"\n"
<< "parsed = xml.parse(uiFile)\n" << "parsed = xml.parse(uiFile)\n"
@@ -710,7 +716,7 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
<< " frame = {}\n" << " frame = {}\n"
<< " pysideuic.compileUi(f, o, indent=0)\n" << " pysideuic.compileUi(f, o, indent=0)\n"
<< " pyc = compile(o.getvalue(), '<string>', 'exec')\n" << " pyc = compile(o.getvalue(), '<string>', 'exec')\n"
<< " exec pyc in frame\n" << " exec(pyc, frame)\n"
<< " #Fetch the base_class and form class based on their type in the xml from designer\n" << " #Fetch the base_class and form class based on their type in the xml from designer\n"
<< " form_class = frame['Ui_%s'%form_class]\n" << " form_class = frame['Ui_%s'%form_class]\n"
<< " base_class = eval('QtGui.%s'%widget_class)\n"; << " base_class = eval('QtGui.%s'%widget_class)\n";
+38 -37
View File
@@ -250,6 +250,7 @@ class _ArchMaterial:
"The Material object" "The Material object"
def __init__(self,obj): def __init__(self,obj):
self.Type = "Material" self.Type = "Material"
obj.Proxy = self obj.Proxy = self
obj.addProperty("App::PropertyString","Description","Arch",QT_TRANSLATE_NOOP("App::Property","A description for this material")) obj.addProperty("App::PropertyString","Description","Arch",QT_TRANSLATE_NOOP("App::Property","A description for this material"))
@@ -259,7 +260,8 @@ class _ArchMaterial:
obj.addProperty("App::PropertyColor","Color","Arch",QT_TRANSLATE_NOOP("App::Property","The color of this material")) obj.addProperty("App::PropertyColor","Color","Arch",QT_TRANSLATE_NOOP("App::Property","The color of this material"))
def onChanged(self,obj,prop): def onChanged(self,obj,prop):
d = None
d = obj.Material
if prop == "Material": if prop == "Material":
if "DiffuseColor" in obj.Material: if "DiffuseColor" in obj.Material:
c = tuple([float(f) for f in obj.Material['DiffuseColor'].strip("()").split(",")]) c = tuple([float(f) for f in obj.Material['DiffuseColor'].strip("()").split(",")])
@@ -283,52 +285,51 @@ class _ArchMaterial:
if hasattr(obj,"Description"): if hasattr(obj,"Description"):
if obj.Description != obj.Material["Description"]: if obj.Description != obj.Material["Description"]:
obj.Description = obj.Material["Description"] obj.Description = obj.Material["Description"]
if "Name" in obj.Material:
if hasattr(obj,"Label"):
if obj.Label != obj.Material["Name"]:
obj.Label = obj.Material["Name"]
elif prop == "Label":
if "Name" in d:
if d["Name"] == obj.Label:
return
d["Name"] = obj.Label
elif prop == "Color": elif prop == "Color":
if hasattr(obj,"Color"): if hasattr(obj,"Color"):
if obj.Material: val = str(obj.Color[:3])
d = obj.Material if "DiffuseColor" in d:
val = str(obj.Color[:3]) if d["DiffuseColor"] == val:
if "DiffuseColor" in d: return
if d["DiffuseColor"] == val: d["DiffuseColor"] = val
return
d["DiffuseColor"] = val
elif prop == "Transparency": elif prop == "Transparency":
if hasattr(obj,"Transparency"): if hasattr(obj,"Transparency"):
if obj.Material: val = str(obj.Transparency)
d = obj.Material if "Transparency" in d:
val = str(obj.Transparency) if d["Transparency"] == val:
if "Transparency" in d: return
if d["Transparency"] == val: d["Transparency"] = val
return
d["Transparency"] = val
elif prop == "ProductURL": elif prop == "ProductURL":
if hasattr(obj,"ProductURL"): if hasattr(obj,"ProductURL"):
if obj.Material: val = obj.ProductURL
d = obj.Material if "ProductURL" in d:
val = obj.ProductURL if d["ProductURL"] == val:
if "ProductURL" in d: return
if d["ProductURL"] == val: obj.Material["ProductURL"] = val
return
obj.Material["ProductURL"] = val
elif prop == "StandardCode": elif prop == "StandardCode":
if hasattr(obj,"StandardCode"): if hasattr(obj,"StandardCode"):
if obj.Material: val = obj.StandardCode
d = obj.Material if "StandardCode" in d:
val = obj.StandardCode if d["StandardCode"] == val:
if "StandardCode" in d: return
if d["StandardCode"] == val: d["StandardCode"] = val
return
d["StandardCode"] = val
elif prop == "Description": elif prop == "Description":
if hasattr(obj,"Description"): if hasattr(obj,"Description"):
if obj.Material: val = obj.Description
d = obj.Material if "Description" in d:
val = obj.Description if d["Description"] == val:
if "Description" in d: return
if d["Description"] == val: d["Description"] = val
return if d and (d != obj.Material):
d["Description"] = val
if d:
obj.Material = d obj.Material = d
if FreeCAD.GuiUp: if FreeCAD.GuiUp:
import FreeCADGui import FreeCADGui
+6 -2
View File
@@ -674,8 +674,12 @@ class _Roof(ArchComponent.Component):
if obj.Base.Shape.Solids: if obj.Base.Shape.Solids:
return obj.Shape return obj.Shape
else : else :
if self.sub: if hasattr(self,"sub"):
return self.sub if self.sub:
return self.sub
else :
self.execute(obj)
return self.sub
else : else :
self.execute(obj) self.execute(obj)
return self.sub return self.sub
+17 -17
View File
@@ -195,7 +195,7 @@ def export(exportList,filename):
outfile.close() outfile.close()
FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + " " + decode(filename) + "\n") FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + " " + decode(filename) + "\n")
if materials: if materials:
outfile = pythonopen(filenamemtl,"wb") outfile = pythonopen(filenamemtl,"w")
outfile.write("# FreeCAD v" + ver[0] + "." + ver[1] + " build" + ver[2] + " Arch module\n") outfile.write("# FreeCAD v" + ver[0] + "." + ver[1] + " build" + ver[2] + " Arch module\n")
outfile.write("# http://www.freecadweb.org\n") outfile.write("# http://www.freecadweb.org\n")
kinds = {"AmbientColor":"Ka ","DiffuseColor":"Kd ","SpecularColor":"Ks ","EmissiveColor":"Ke ","Transparency":"d "} kinds = {"AmbientColor":"Ka ","DiffuseColor":"Kd ","SpecularColor":"Ks ","EmissiveColor":"Ke ","Transparency":"d "}
@@ -219,23 +219,23 @@ def export(exportList,filename):
FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + ' ' + decode(filenamemtl) + "\n") FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + ' ' + decode(filenamemtl) + "\n")
def decode(name): #def decode(name):
"decodes encoded strings" # "decodes encoded strings"
try: # try:
decodedName = (name.decode("utf8")) # decodedName = (name.decode("utf8"))
except UnicodeDecodeError: # except UnicodeDecodeError:
try: # try:
decodedName = (name.decode("latin1")) # decodedName = (name.decode("latin1"))
except UnicodeDecodeError: # except UnicodeDecodeError:
FreeCAD.Console.PrintError(translate("Arch","Error: Couldn't determine character encoding")) # FreeCAD.Console.PrintError(translate("Arch","Error: Couldn't determine character encoding"))
decodedName = name # decodedName = name
return decodedName # return decodedName
def open(filename): def open(filename):
"called when freecad wants to open a file" "called when freecad wants to open a file"
docname = (os.path.splitext(os.path.basename(filename))[0]).encode("utf8") docname = (os.path.splitext(os.path.basename(filename))[0])
doc = FreeCAD.newDocument(docname) doc = FreeCAD.newDocument(docname.encode("utf8"))
doc.Label = decode(docname) doc.Label = docname
return insert(filename,doc.Name) return insert(filename,doc.Name)
def insert(filename,docname): def insert(filename,docname):
@@ -246,7 +246,7 @@ def insert(filename,docname):
doc = FreeCAD.newDocument(docname) doc = FreeCAD.newDocument(docname)
FreeCAD.ActiveDocument = doc FreeCAD.ActiveDocument = doc
with pythonopen(filename,"rb") as infile: with pythonopen(filename,"r") as infile:
verts = [] verts = []
facets = [] facets = []
activeobject = None activeobject = None
@@ -257,7 +257,7 @@ def insert(filename,docname):
if line[:7] == "mtllib ": if line[:7] == "mtllib ":
matlib = os.path.join(os.path.dirname(filename),line[7:]) matlib = os.path.join(os.path.dirname(filename),line[7:])
if os.path.exists(matlib): if os.path.exists(matlib):
with pythonopen(matlib,"rb") as matfile: with pythonopen(matlib,"r") as matfile:
mname = None mname = None
color = None color = None
trans = None trans = None
+3 -22
View File
@@ -87,22 +87,13 @@ def errorDXFLib(gui):
if gui: if gui:
from PySide import QtGui, QtCore from PySide import QtGui, QtCore
from DraftTools import translate from DraftTools import translate
if float(FreeCAD.Version()[0]+"."+FreeCAD.Version()[1]) >= 0.17: message = translate("Draft","""Download of dxf libraries failed.
message = translate("Draft","""Download of dxf libraries failed.
Please install the dxf Library addon manually Please install the dxf Library addon manually
from menu Tools -> Addon Manager""") from menu Tools -> Addon Manager""")
else:
message = translate("Draft","""Download of dxf libraries failed.
Please download and install them manually.
See complete instructions at
http://www.freecadweb.org/wiki/Dxf_Importer_Install""")
QtGui.QMessageBox.information(None,"",message) QtGui.QMessageBox.information(None,"",message)
else: else:
FreeCAD.Console.PrintWarning("The DXF import/export libraries needed by FreeCAD to handle the DXF format are not installed.\n") FreeCAD.Console.PrintWarning("The DXF import/export libraries needed by FreeCAD to handle the DXF format are not installed.\n")
if float(FreeCAD.Version()[0]+"."+FreeCAD.Version()[1]) >= 0.17: FreeCAD.Console.PrintWarning("Please install the dxf Library addon from Tools -> Addons Manager\n")
FreeCAD.Console.PrintWarning("Please install the dxf Library addon from Tools -> Addons Manager\n")
else:
FreeCAD.Console.PrintWarning("Please check https://github.com/yorikvanhavre/Draft-dxf-importer\n")
break break
progressbar.stop() progressbar.stop()
sys.path.append(FreeCAD.ConfigGet("UserAppData")) sys.path.append(FreeCAD.ConfigGet("UserAppData"))
@@ -110,17 +101,7 @@ http://www.freecadweb.org/wiki/Dxf_Importer_Install""")
if gui: if gui:
from PySide import QtGui, QtCore from PySide import QtGui, QtCore
from DraftTools import translate from DraftTools import translate
if float(FreeCAD.Version()[0]+"."+FreeCAD.Version()[1]) >= 0.17: message = translate('draft',"""The DXF import/export libraries needed by FreeCAD to handle
message = translate('draft',"""The DXF import/export libraries needed by FreeCAD to handle
the DXF format were not found on this system.
Please either enable FreeCAD to download these libraries:
1 - Load Draft workbench
2 - Menu Edit > Preferences > Import-Export > DXF > Enable downloads
Or install the libraries manually by installing the dxf-Library addon
from menu Tools -> Addon Manager.
To enabled FreeCAD to download these libraries, answer Yes.""")
else:
message = translate('draft',"""The DXF import/export libraries needed by FreeCAD to handle
the DXF format were not found on this system. the DXF format were not found on this system.
Please either enable FreeCAD to download these libraries: Please either enable FreeCAD to download these libraries:
1 - Load Draft workbench 1 - Load Draft workbench
+3 -3
View File
@@ -295,14 +295,14 @@ def fill_femresult_mechanical(res_obj, result_set):
if len(Peeq) > 0: if len(Peeq) > 0:
if len(Peeq.values()) != len(disp.values()): if len(Peeq.values()) != len(disp.values()):
Pe = [] Pe = []
Pe_extra_nodes = Peeq.values() Pe_extra_nodes = list(Peeq.values())
nodes = len(disp.values()) nodes = len(disp.values())
for i in range(nodes): for i in range(nodes):
Pe_value = Pe_extra_nodes[i] Pe_value = Pe_extra_nodes[i]
Pe.append(Pe_value) Pe.append(Pe_value)
res_obj.Peeq = Pe res_obj.Peeq = Pe
else: else:
res_obj.Peeq = Peeq.values() res_obj.Peeq = list(Peeq.values())
# fill res_obj.Temperature if they exist # fill res_obj.Temperature if they exist
# TODO, check if it is possible to have Temperature without disp, we would need to set NodeNumbers than # TODO, check if it is possible to have Temperature without disp, we would need to set NodeNumbers than
@@ -311,7 +311,7 @@ def fill_femresult_mechanical(res_obj, result_set):
if len(Temperature) > 0: if len(Temperature) > 0:
if len(Temperature.values()) != len(disp.values()): if len(Temperature.values()) != len(disp.values()):
Temp = [] Temp = []
Temp_extra_nodes = Temperature.values() Temp_extra_nodes = list(Temperature.values())
nodes = len(disp.values()) nodes = len(disp.values())
for i in range(nodes): for i in range(nodes):
Temp_value = Temp_extra_nodes[i] Temp_value = Temp_extra_nodes[i]
+2 -2
View File
@@ -536,11 +536,11 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
ccx_path = FreeCAD.getHomePath() + "bin/ccx.exe" ccx_path = FreeCAD.getHomePath() + "bin/ccx.exe"
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx").SetString("ccxBinaryPath", ccx_path) FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx").SetString("ccxBinaryPath", ccx_path)
self.ccx_binary = ccx_path self.ccx_binary = ccx_path
elif system() == "Linux": elif system() in ("Linux", "Darwin"):
p1 = subprocess.Popen(['which', 'ccx'], stdout=subprocess.PIPE) p1 = subprocess.Popen(['which', 'ccx'], stdout=subprocess.PIPE)
if p1.wait() == 0: if p1.wait() == 0:
if sys.version_info.major >= 3: if sys.version_info.major >= 3:
ccx_path = str(p1.stdout.read()).split('\n')[0] ccx_path = p1.stdout.read().decode("utf8").split('\n')[0]
else: else:
ccx_path = p1.stdout.read().split('\n')[0] ccx_path = p1.stdout.read().split('\n')[0]
elif p1.wait() == 1: elif p1.wait() == 1:
@@ -138,8 +138,15 @@ def cmdCreateImageScaling(name):
def accept(self): def accept(self):
sel = FreeCADGui.Selection.getSelection() sel = FreeCADGui.Selection.getSelection()
try: try:
locale=QtCore.QLocale.system() try:
d, ok = locale.toFloat(str(eval(self.lineEdit.text()))) q = FreeCAD.Units.parseQuantity(self.lineEdit.text())
d = q.Value
if q.Unit == FreeCAD.Units.Unit(): # plain number
ok = True
elif q.Unit == FreeCAD.Units.Length:
ok = True
except:
ok = False
if not ok: if not ok:
raise ValueError raise ValueError
s=d/self.distance s=d/self.distance
+7 -7
View File
@@ -383,8 +383,8 @@ void PartGui::DimensionLinear::setupDimension()
//dimension arrows //dimension arrows
float dimLength = (point2.getValue()-point1.getValue()).length(); float dimLength = (point2.getValue()-point1.getValue()).length();
float coneHeight = dimLength * .05; float coneHeight = dimLength * 0.05;
float coneRadius = coneHeight / 2; float coneRadius = coneHeight * 0.5;
SoCone *cone = new SoCone(); SoCone *cone = new SoCone();
cone->bottomRadius.setValue(coneRadius); cone->bottomRadius.setValue(coneRadius);
@@ -392,8 +392,8 @@ void PartGui::DimensionLinear::setupDimension()
char lStr[100]; char lStr[100];
char rStr[100]; char rStr[100];
snprintf(lStr, sizeof(lStr), "translation %.2f 0.0 0.0", coneHeight*0.5); snprintf(lStr, sizeof(lStr), "translation %.6f 0.0 0.0", coneHeight * 0.5);
snprintf(rStr, sizeof(rStr), "translation 0.0 -%.2f 0.0", coneHeight*0.5); snprintf(rStr, sizeof(rStr), "translation 0.0 -%.6f 0.0", coneHeight * 0.5);
setPart("leftArrow.shape", cone); setPart("leftArrow.shape", cone);
set("leftArrow.transform", "rotation 0.0 0.0 1.0 1.5707963"); set("leftArrow.transform", "rotation 0.0 0.0 1.0 1.5707963");
@@ -1072,7 +1072,7 @@ void PartGui::DimensionAngular::setupDimension()
//dimension arrows //dimension arrows
float coneHeight = radius.getValue() * 0.1; float coneHeight = radius.getValue() * 0.1;
float coneRadius = coneHeight / 2; float coneRadius = coneHeight * 0.5;
SoCone *cone = new SoCone(); SoCone *cone = new SoCone();
cone->bottomRadius.setValue(coneRadius); cone->bottomRadius.setValue(coneRadius);
@@ -1080,8 +1080,8 @@ void PartGui::DimensionAngular::setupDimension()
char str1[100]; char str1[100];
char str2[100]; char str2[100];
snprintf(str1, sizeof(str1), "translation 0.0 %.2f 0.0", coneHeight*0.5); snprintf(str1, sizeof(str1), "translation 0.0 %.6f 0.0", coneHeight * 0.5);
snprintf(str2, sizeof(str2), "translation 0.0 -%.2f 0.0", coneHeight*0.5); snprintf(str2, sizeof(str2), "translation 0.0 -%.6f 0.0", coneHeight * 0.5);
setPart("arrow1.shape", cone); setPart("arrow1.shape", cone);
set("arrow1.localTransform", "rotation 0.0 0.0 1.0 3.1415927"); set("arrow1.localTransform", "rotation 0.0 0.0 1.0 3.1415927");
@@ -89,7 +89,7 @@ class ObjectOp(PathOp.ObjectOp):
Obviously this is as fragile as can be, but currently the best we can do while the panel sheets Obviously this is as fragile as can be, but currently the best we can do while the panel sheets
hide the actual features from Path and they can't be referenced directly. hide the actual features from Path and they can't be referenced directly.
''' '''
ids = string.split(sub, '.') ids = sub.split(".")
holeId = int(ids[0]) holeId = int(ids[0])
wireId = int(ids[1]) wireId = int(ids[1])
edgeId = int(ids[2]) edgeId = int(ids[2])
+8 -2
View File
@@ -1195,11 +1195,17 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
return true; return true;
} }
case STATUS_SKETCH_UseRubberBand: { case STATUS_SKETCH_UseRubberBand: {
// Here we must use the device-pixel-ratio to compute the correct y coordinate (#0003130)
#if QT_VERSION >= 0x050600
qreal dpr = viewer->getGLWidget()->devicePixelRatioF();
#else
qreal dpr = 1;
#endif
newCursorPos = cursorPos; newCursorPos = cursorPos;
rubberband->setCoords(prvCursorPos.getValue()[0], rubberband->setCoords(prvCursorPos.getValue()[0],
viewer->getGLWidget()->height() - prvCursorPos.getValue()[1], viewer->getGLWidget()->height()*dpr - prvCursorPos.getValue()[1],
newCursorPos.getValue()[0], newCursorPos.getValue()[0],
viewer->getGLWidget()->height() - newCursorPos.getValue()[1]); viewer->getGLWidget()->height()*dpr - newCursorPos.getValue()[1]);
viewer->redraw(); viewer->redraw();
return true; return true;
} }
+36 -4
View File
@@ -1,4 +1,36 @@
install(FILES org.freecadweb.FreeCAD.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo) include(GNUInstallDirs)
install(FILES org.freecadweb.FreeCAD.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
install(FILES org.freecadweb.FreeCAD.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps) if(NOT DEFINED APPDATA_RELEASE_DATE)
install(FILES org.freecadweb.FreeCAD.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages) if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
execute_process(COMMAND git log -1 --pretty=%cd --date=short
OUTPUT_VARIABLE APPDATA_RELEASE_DATE
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
file(TIMESTAMP "${CMAKE_SOURCE_DIR}/CMakeLists.txt" APPDATA_RELEASE_DATE "%Y-%m-%d")
endif()
endif()
configure_file(
org.freecadweb.FreeCAD.appdata.xml.in
${CMAKE_BINARY_DIR}/org.freecadweb.FreeCAD.appdata.xml
)
install(
FILES ${CMAKE_BINARY_DIR}/org.freecadweb.FreeCAD.appdata.xml
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo
)
install(
FILES org.freecadweb.FreeCAD.desktop
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications
)
install(
FILES org.freecadweb.FreeCAD.svg
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps
)
install(
FILES org.freecadweb.FreeCAD.xml
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages
)
@@ -29,8 +29,8 @@
<url type="help">https://forum.freecadweb.org</url> <url type="help">https://forum.freecadweb.org</url>
<url type="donation">https://www.freecadweb.org/wiki/Donate</url> <url type="donation">https://www.freecadweb.org/wiki/Donate</url>
<update_contact>yorik_AT_uncreated.net</update_contact> <update_contact>yorik_AT_uncreated.net</update_contact>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1"/>
<releases> <releases>
<release version="0.17" date="2018-04-06"></release> <release version="@PACKAGE_VERSION@" date="@APPDATA_RELEASE_DATE@"/>
</releases> </releases>
</component> </component>