Compare commits

...

14 Commits

Author SHA1 Message Date
Yorik van Havre 3129ae4296 AddonManager: Skip non-github addons 2019-07-12 18:08:08 -03:00
Abdullah Tahiri 0572853dbd Sketcher: Fix Carbon copy leads to unsolvable sketch
====================================================

fixes #3973

https://forum.freecadweb.org/viewtopic.php?p=316251#p316198

This commit disables an old "axis orientation correction mode", which tried to
solve a problem with orientation of the axis. It never worked fine and it should
have never been introduced, as everything it intends to do should be done by
setting the appropriate placement offset.
2019-06-28 10:49:05 +02:00
Abdullah Tahiri 2f0c3a79fa Sketcher: Fix carbon copy construction points
=============================================

fixes #3926

Points made of construction type are special non-constrainable points, such as (current) bspline knots.

This was not intended in Carbon Copy.
2019-06-28 10:48:56 +02:00
wmayer 0f29891a98 fixes #0003993: Memory leak with Python3 2019-06-24 14:32:42 +02:00
wmayer 3eaf87b2dc code simplification in PythonWrapper 2019-06-22 14:38:49 +02:00
wmayer 60fd668d5c issue #0003984: Creating a Path Job object fails with 'PySide2.QtWidgets.QDialog' object has no attribute 'templateGroup' 2019-06-22 14:38:20 +02:00
Russell Johnson 4351058504 Fixes bug #4008: removes phantom path cause
Job object was base of transformations, rather than Job base(clone).
2019-06-22 14:34:51 +02:00
wmayer f2f4b44792 Fix crash in case encoding of Python paths fails 2019-06-21 16:33:18 +02:00
luz.paz 90ff921ef7 [Material] Respect unicode filenames
Fixes #4027
2019-06-21 16:27:41 +02:00
Zheng, Lei 662aebd881 BrowserView: fix QWebEngine crash 2019-06-21 16:27:12 +02:00
wmayer d2f0c4f33d Py3: no __builtin__ module available 2019-06-17 17:11:14 +02:00
wmayer b80d000aff fixes 0004010: Box Selection + Part -> MakeCompound will crash FreeCAD 2019-06-12 11:26:21 +02:00
Bernd Hahnebach 627ae70a53 FEM: solver elmer tasks, Py3 decode fix 2019-06-11 15:49:12 +02:00
wmayer a261a55adf make OpenSCAD utilities working again with Py2 2019-06-07 13:09:41 +02:00
14 changed files with 160 additions and 99 deletions
+5 -1
View File
@@ -1529,7 +1529,11 @@ void Application::initConfig(int argc, char ** argv)
PyImport_AppendInittab ("FreeCAD", init_freecad_module);
PyImport_AppendInittab ("__FreeCADBase__", init_freecad_base_module);
#endif
mConfig["PythonSearchPath"] = Interpreter().init(argc,argv);
const char* pythonpath = Interpreter().init(argc,argv);
if (pythonpath)
mConfig["PythonSearchPath"] = pythonpath;
else
Base::Console().Warning("Encoding of Python paths failed\n");
// Parse the options that have impact on the init process
ParseOptions(argc,argv);
+4 -4
View File
@@ -2033,25 +2033,25 @@ namespace Py
}
String()
: SeqBase<Char>( PyUnicode_FromString( "" ) )
: SeqBase<Char>( PyUnicode_FromString( "" ), true )
{
validate();
}
String( const char *latin1 )
: SeqBase<Char>( PyUnicode_FromString( latin1 ) )
: SeqBase<Char>( PyUnicode_FromString( latin1 ), true )
{
validate();
}
String( const std::string &latin1 )
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1.c_str(), latin1.size() ) )
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1.c_str(), latin1.size() ), true )
{
validate();
}
String( const char *latin1, Py_ssize_t size )
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1, size ) )
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1, size ), true )
{
validate();
}
+48 -15
View File
@@ -232,6 +232,28 @@ Py::Object qt_wrapInstance(qttype object, const char* className,
return func.apply(arguments);
}
const char* qt_identifyType(QObject* ptr, const char* pyside)
{
PyObject* module = PyImport_ImportModule(pyside);
if (!module) {
std::string error = "Cannot load ";
error += pyside;
error += " module";
throw Py::Exception(PyExc_ImportError, error);
}
Py::Module qtmod(module);
const QMetaObject* metaObject = ptr->metaObject();
while (metaObject) {
const char* className = metaObject->className();
if (qtmod.getDict().hasKey(className))
return className;
metaObject = metaObject->superClass();
}
return nullptr;
}
void* qt_getCppPointer(const Py::Object& pyobject, const char* shiboken, const char* unwrap)
{
// https://github.com/PySide/Shiboken/blob/master/shibokenmodule/typesystem_shiboken.xml
@@ -475,39 +497,50 @@ bool PythonWrapper::loadWidgetsModule()
void PythonWrapper::createChildrenNameAttributes(PyObject* root, QObject* object)
{
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
Q_FOREACH (QObject* child, object->children()) {
const QByteArray name = child->objectName().toLocal8Bit();
if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
bool hasAttr = PyObject_HasAttrString(root, name.constData());
if (!hasAttr) {
#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2)
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], child));
#else
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide_QtCoreTypes[SBK_QOBJECT_IDX], child));
#endif
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType*>(Shiboken::SbkType<QObject>()), child));
PyObject_SetAttrString(root, name.constData(), pyChild);
#elif QT_VERSION >= 0x050000
const char* className = qt_identifyType(child, "PySide2.QtWidgets");
if (!className) {
if (qobject_cast<QWidget*>(child))
className = "QWidget";
else
className = "QObject";
}
Py::Object pyChild(qt_wrapInstance<QObject*>(child, className, "shiboken2", "PySide2.QtWidgets", "wrapInstance"));
PyObject_SetAttrString(root, name.constData(), pyChild.ptr());
#else
const char* className = qt_identifyType(child, "PySide.QtGui");
if (!className) {
if (qobject_cast<QWidget*>(child))
className = "QWidget";
else
className = "QObject";
}
Py::Object pyChild(qt_wrapInstance<QObject*>(child, className, "shiboken", "PySide.QtGui", "wrapInstance"));
PyObject_SetAttrString(root, name.constData(), pyChild.ptr());
#endif
}
createChildrenNameAttributes(root, child);
}
createChildrenNameAttributes(root, child);
}
#else
Q_UNUSED(root);
Q_UNUSED(object);
#endif
}
void PythonWrapper::setParent(PyObject* pyWdg, QObject* parent)
{
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
if (parent) {
#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2)
Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide2_QtGuiTypes[SBK_QWIDGET_IDX], parent));
#else
Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide_QtGuiTypes[SBK_QWIDGET_IDX], parent));
#endif
Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType*>(Shiboken::SbkType<QWidget>()), parent));
Shiboken::Object::setParent(pyParent, pyWdg);
}
#else
+11 -7
View File
@@ -577,14 +577,18 @@ class UpdateWorker(QtCore.QThread):
name = re.findall("title=\"(.*?) @",l)[0]
self.info_label.emit(name)
#url = re.findall("title=\"(.*?) @",l)[0]
url = "https://github.com/" + re.findall("href=\"\/(.*?)\/tree",l)[0]
addondir = moddir + os.sep + name
#print ("found:",name," at ",url)
if not os.path.exists(addondir):
state = 0
try:
url = "https://github.com/" + re.findall("href=\"\/(.*?)\/tree",l)[0]
except:
pass
else:
state = 1
repos.append([name,url,state])
addondir = moddir + os.sep + name
#print ("found:",name," at ",url)
if not os.path.exists(addondir):
state = 0
else:
state = 1
repos.append([name,url,state])
if not repos:
self.info_label.emit(translate("AddonsInstaller", "Unable to download addon list."))
else:
+6 -1
View File
@@ -28,6 +28,8 @@ __url__ = "http://www.freecadweb.org"
import subprocess
import os.path
import sys
import femtools.femutils as femutils
from .. import run
@@ -112,7 +114,10 @@ class Solve(run.Solve):
def _updateOutput(self, output):
if self.solver.ElmerOutput is None:
self._createOutput()
self.solver.ElmerOutput.Text = output.decode("utf-8")
if sys.version_info.major >= 3:
self.solver.ElmerOutput.Text = output
else:
self.solver.ElmerOutput.Text = output.decode("utf-8")
def _createOutput(self):
self.solver.ElmerOutput = self.analysis.Document.addObject(
+5 -3
View File
@@ -22,11 +22,15 @@
#* Milos Koutny 2010 *
#***************************************************************************/
import FreeCAD, Part, os, FreeCADGui, __builtin__
import FreeCAD, Part, os, FreeCADGui
from FreeCAD import Base
from math import *
import ImportGui
# to distinguish python built-in open function from the one declared here
if open.__module__ in ['__builtin__','io']:
pythonopen = open
##########################################################
# Script version dated 19-Jan-2012 #
##########################################################
@@ -54,8 +58,6 @@ IDF_diag_path="/tmp" # path for output of footprint.lst and missing_models.lst
# End config section do not touch code below #
########################################################################################
pythonopen = __builtin__.open # to distinguish python built-in open function from the one declared here
def open(filename):
"""called when freecad opens an Emn file"""
docname = os.path.splitext(os.path.basename(filename))[0]
+1 -1
View File
@@ -62,7 +62,7 @@ def importFCMat(fileName):
Config = configparser.RawConfigParser()
Config.optionxform = str
Config.read(fileName)
Config.read(fileName, encoding='utf-8') # respect unicode filenames
dict1 = {}
for section in Config.sections():
options = Config.options(section)
+19 -9
View File
@@ -42,6 +42,8 @@ except AttributeError:
return QtGui.QApplication.translate(context, text, None)
import io
import sys
PY2 = sys.version_info.major == 2
try:
import FreeCAD
@@ -144,18 +146,23 @@ def callopenscad(inputfilename,outputfilename=None,outputext='csg',keepname=Fals
import FreeCAD,os,subprocess,tempfile,time
def check_output2(*args,**kwargs):
kwargs.update({'stdout':subprocess.PIPE,'stderr':subprocess.PIPE})
p=subprocess.Popen(*args,**kwargs)
if PY2:
p=subprocess.Popen(*args)
else:
p=subprocess.Popen(*args,**kwargs)
stdoutd,stderrd = p.communicate()
stdoutd = stdoutd.decode("utf8")
stderrd = stderrd.decode("utf8")
if not PY2:
stdoutd = stdoutd.decode("utf8")
stderrd = stderrd.decode("utf8")
if p.returncode != 0:
raise OpenSCADError('%s %s\n' % (stdoutd.strip(),stderrd.strip()))
#raise Exception,'stdout %s\n stderr%s' %(stdoutd,stderrd)
if stderrd.strip():
FreeCAD.Console.PrintWarning(stderrd+u'\n')
if stdoutd.strip():
FreeCAD.Console.PrintMessage(stdoutd+u'\n')
return stdoutd
if not PY2:
if stderrd.strip():
FreeCAD.Console.PrintWarning(stderrd+u'\n')
if stdoutd.strip():
FreeCAD.Console.PrintMessage(stdoutd+u'\n')
return stdoutd
osfilename = FreeCAD.ParamGet(\
"User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
@@ -182,7 +189,10 @@ def callopenscadstring(scadstr,outputext='csg'):
dir1=tempfile.gettempdir()
inputfilename=os.path.join(dir1,'%s.scad' % next(tempfilenamegen))
inputfile = io.open(inputfilename,'w', encoding="utf8")
inputfile.write(scadstr)
if PY2:
inputfile.write(scadstr.decode('utf8'))
else:
inputfile.write(scadstr)
inputfile.close()
outputfilename = callopenscad(inputfilename,outputext=outputext,\
keepname=True)
+18 -10
View File
@@ -66,21 +66,29 @@ App::DocumentObjectExecReturn *Compound::execute(void)
TopoDS_Compound comp;
builder.MakeCompound(comp);
// avoid duplicates without changing the order
// See also ViewProviderCompound::updateData
std::set<DocumentObject*> tempLinks;
const std::vector<DocumentObject*>& links = Links.getValues();
for (std::vector<DocumentObject*>::const_iterator it = links.begin(); it != links.end(); ++it) {
if (*it && (*it)->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
Part::Feature* fea = static_cast<Part::Feature*>(*it);
const TopoDS_Shape& sh = fea->Shape.getValue();
if (!sh.IsNull()) {
builder.Add(comp, sh);
TopTools_IndexedMapOfShape faceMap;
TopExp::MapShapes(sh, TopAbs_FACE, faceMap);
ShapeHistory hist;
hist.type = TopAbs_FACE;
for (int i=1; i<=faceMap.Extent(); i++) {
hist.shapeMap[i-1].push_back(countFaces++);
auto pos = tempLinks.insert(fea);
if (pos.second) {
const TopoDS_Shape& sh = fea->Shape.getValue();
if (!sh.IsNull()) {
builder.Add(comp, sh);
TopTools_IndexedMapOfShape faceMap;
TopExp::MapShapes(sh, TopAbs_FACE, faceMap);
ShapeHistory hist;
hist.type = TopAbs_FACE;
for (int i=1; i<=faceMap.Extent(); i++) {
hist.shapeMap[i-1].push_back(countFaces++);
}
history.push_back(hist);
}
history.push_back(hist);
}
}
}
+8 -4
View File
@@ -908,11 +908,15 @@ void CmdPartCompound::activated(int iMsg)
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
std::stringstream str;
std::vector<std::string> tempSelNames;
// avoid duplicates without changing the order
std::set<std::string> tempSelNames;
str << "App.activeDocument()." << FeatName << ".Links = [";
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
str << "App.activeDocument()." << it->FeatName << ",";
tempSelNames.push_back(it->FeatName);
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it) {
auto pos = tempSelNames.insert(it->FeatName);
if (pos.second) {
str << "App.activeDocument()." << it->FeatName << ",";
}
}
str << "]";
+18
View File
@@ -72,6 +72,24 @@ void ViewProviderCompound::updateData(const App::Property* prop)
(prop)->getValues();
Part::Compound* objComp = static_cast<Part::Compound*>(getObject());
std::vector<App::DocumentObject*> sources = objComp->Links.getValues();
if (hist.size() != sources.size()) {
// avoid duplicates without changing the order
// See also Compound::execute
std::set<App::DocumentObject*> tempSources;
std::vector<App::DocumentObject*> filter;
for (std::vector<App::DocumentObject*>::iterator it = sources.begin(); it != sources.end(); ++it) {
Part::Feature* objBase = dynamic_cast<Part::Feature*>(*it);
if (objBase) {
auto pos = tempSources.insert(objBase);
if (pos.second) {
filter.push_back(objBase);
}
}
}
sources = filter;
}
if (hist.size() != sources.size())
return;
+4
View File
@@ -1019,6 +1019,10 @@ class TaskPanel:
Draft.move(sel.Object, by)
def updateSelection(self):
# Remove Job object if present in Selection: source of phantom paths
if self.obj in FreeCADGui.Selection.getSelection():
FreeCADGui.Selection.removeSelection(self.obj)
sel = FreeCADGui.Selection.getSelectionEx()
if len(sel) == 1 and len(sel[0].SubObjects) == 1:
+8 -44
View File
@@ -5140,7 +5140,7 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
for (std::vector<Part::Geometry *>::const_iterator it=svals.begin(); it != svals.end(); ++it){
Part::Geometry *geoNew = (*it)->copy();
if(construction) {
if(construction && geoNew->getTypeId() != Part::GeomPoint::getClassTypeId()) {
geoNew->Construction = true;
}
newVals.push_back(geoNew);
@@ -5174,11 +5174,13 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
int sourceid = 0;
for (std::vector< Sketcher::Constraint * >::const_iterator it= scvals.begin(); it != scvals.end(); ++it,nextcid++,sourceid++) {
if ((*it)->Type == Sketcher::Distance ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Angle ||
(*it)->Type == Sketcher::SnellsLaw) {
if ((*it)->Type == Sketcher::Distance ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Angle ||
(*it)->Type == Sketcher::SnellsLaw ||
(*it)->Type == Sketcher::DistanceX ||
(*it)->Type == Sketcher::DistanceY ) {
// then we link its value to the parent
// (there is a plausible alternative for a slightly different use case to copy the expression of the parent if one is existing)
if ((*it)->isDriving) {
@@ -5191,45 +5193,7 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
setExpression(Constraints.createPath(nextcid), expr);
}
}
else if ((*it)->Type == Sketcher::DistanceX) {
// then we link its value to the parent
// (there is a plausible alternative for a slightly different use case to copy the expression of the parent if one is existing)
if ((*it)->isDriving) {
App::ObjectIdentifier spath = psObj->Constraints.createPath(sourceid);
if(xinv) {
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, std::string(1,'-') + spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
setExpression(Constraints.createPath(nextcid), expr);
}
else {
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
setExpression(Constraints.createPath(nextcid), expr);
}
}
}
else if ((*it)->Type == Sketcher::DistanceY ) {
// then we link its value to the parent
// (there is a plausible alternative for a slightly different use case to copy the expression of the parent if one is existing)
if ((*it)->isDriving) {
App::ObjectIdentifier spath = psObj->Constraints.createPath(sourceid);
if(yinv) {
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, std::string(1,'-') + spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
setExpression(Constraints.createPath(nextcid), expr);
}
else {
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
setExpression(Constraints.createPath(nextcid), expr);
}
}
}
}
+5
View File
@@ -227,6 +227,11 @@ BrowserView::BrowserView(QWidget* parent)
isLoading(false),
textSizeMultiplier(1.0)
{
#if defined(QTWEBENGINE)
// Otherwise cause crash on exit, probably due to double deletion
setAttribute(Qt::WA_DeleteOnClose,false);
#endif
view = new WebView(this);
setCentralWidget(view);