Current best practices to solve the 'pivy' problem?

Having trouble installing or compiling FreeCAD? Get help here.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
kevinz
Posts: 68
Joined: Fri Oct 18, 2019 2:58 pm

Current best practices to solve the 'pivy' problem?

Post by kevinz »

Hello, all. Happy New Year!

I'd like advice on how to best solve the 'pivy' problem with Text Draw. I think this also affects Draft->Shape from Text. It mostly manifests itself in error messages like, "<built-in function SoFieldContainer_getField> returned a result with an exception set." This seems to be caused by an incompatibility with Python3 (3.10? 3.11?).

Some threads I've read advocate downloading pivy-0.6.8... and installing it in /usr/lib/python3.10/site-packages/pivy. Others suggest using an AppImage. I guess another option is building from source.

What's the current best advice to solve this problem? I've built from source before, but it can be a nightmare if there are lots of dependancies to track down. I think I'm currently using the version from the ppa, because of this line in my history: "sudo add-apt-repository ppa:freecad-maintainers/freecad-stable" See also the Help output below my signature.

Thanks for any advice or guidance. I appreciate all the work and effort that goes into FreeCAD, and I enjoy using and creating with it.

-Kevin

Code: Select all

OS: Ubuntu 22.04.1 LTS (ubuntu:GNOME/ubuntu)
Word size of FreeCAD: 64-bit
Version: 0.20.1.
Build type: Release
Branch: unknown
Hash: 22f524c0c755003c12234fab1bad6a9f696b661a
Python 3.10.6, Qt 5.15.3, Coin 4.0.0, Vtk 9.1.0, OCC 7.5.1
Locale: English/United States (en_US)
Installed mods: 
  * Help 1.0.3
Also:

Code: Select all

$ apt-cache policy freecad
freecad:
  Installed: 2:0.20.1+dfsg1~202210271541~ubuntu22.04.1
  Candidate: 2:0.20.1+dfsg1~202210271541~ubuntu22.04.1
  Version table:
 *** 2:0.20.1+dfsg1~202210271541~ubuntu22.04.1 500
        500 https://ppa.launchpadcontent.net/freecad-maintainers/freecad-stable/ubuntu jammy/main amd64 Packages
        500 https://ppa.launchpadcontent.net/freecad-maintainers/freecad-stable/ubuntu jammy/main i386 Packages
        100 /var/lib/dpkg/status
     0.19.2+dfsg1-3ubuntu1 500
        500 http://us.archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
        500 http://us.archive.ubuntu.com/ubuntu jammy/universe i386 Packages
$ 
User avatar
adrianinsaval
Veteran
Posts: 5548
Joined: Thu Apr 05, 2018 5:15 pm

Re: Current best practices to solve the 'pivy' problem?

Post by adrianinsaval »

pivy is a python package so AFAIK you don't need to rebuild freecad to match a specific version, using the appimage is the easiest method but if you prefer to use apt package installing pivy 0.6.8 should work, I think wmayer made a post explaining how to install a newer pivy on ubuntu not too long ago, search his posts.
kevinz
Posts: 68
Joined: Fri Oct 18, 2019 2:58 pm

Re: Current best practices to solve the 'pivy' problem?

Post by kevinz »

@adrianinsaval , thanks so much for the suggestion. Minor frustration (that I don't expect you to solve or answer): @wmayer is so helpful and posts so much that they have almost 2000 pages of mentions, and searching for 'wmayer' as an author and 'pivy' as a term is rejected because 'pivy' is too common. Oh, well... Have to run now to do something else, but will pursue this when I return.

Thanks, again.

-Kevin
wmayer
Founder
Posts: 20303
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Current best practices to solve the 'pivy' problem?

Post by wmayer »

https://forum.freecadweb.org/viewtopic. ... 42#p650542

Edit:
I will repost it here too.

Edit2: The copied posting includes a further step about increasing the version number.
kevinz
Posts: 68
Joined: Fri Oct 18, 2019 2:58 pm

Re: Current best practices to solve the 'pivy' problem?

Post by kevinz »

@wmayer , thanks so much!

-Kevin
wmayer
Founder
Posts: 20303
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Current best practices to solve the 'pivy' problem?

Post by wmayer »

In order to build a pivy Debian package with the fixes from master for 22.04 follow these steps:
  • Install the packages debhelper, devscripts, dh-python, python3-all-dev, python3-all-dbg, libsoqt520-dev, libsimage-dev
    Further packages might be required but debuild will tell you what's still missing.
  • Download http://archive.ubuntu.com/ubuntu/pool/u ... build6.dsc, http://archive.ubuntu.com/ubuntu/pool/u ... rig.tar.gz and http://archive.ubuntu.com/ubuntu/pool/u ... ian.tar.xz
  • Get the latest pivy sources from https://github.com/coin3d/pivy
  • Open a terminal and switch to the directory of the above downloaded files and run:

    Code: Select all

    dpkg-source -x pivy_0.6.5-1build6.dsc
    
    This will extract the archive and apply the patches.
  • Open a graphical diff tool like meld and compare the master with the extracted pivy sources and copy over the relevant changes.
  • Make sure that the new package has a higher version number as otherwise for every update using APT the official package will be re-installed. Therefore edit the changelog file and add a further entry. The version number should be

    Code: Select all

    pivy (0.6.5-1build7) jammy; urgency=medium
  • Code: Select all

    dpkg-source --commit
    and follow the instructions
  • debuild
  • Install the newly created Debian package python3-pivy_0.6.5-1build6_amd64.deb
After installing the package all pivy errors are gone.

Hint: If you use another Debian derivative then the procedure is almost the same. You only have to make sure to get the .dsc, original source tarball and Debian patch file that match with your OS version.


If you are unsure of what changes to apply from master here is my patch file:

Code: Select all

Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 pivy (0.6.5-1build6) jammy; urgency=medium
 .
   * No-change rebuild with Python 3.10 only
Author: Graham Inggs <ginggs@ubuntu.com>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2022-12-31

--- pivy-0.6.5.orig/Inventor/fields/SoMFVec2f.i
+++ pivy-0.6.5/Inventor/fields/SoMFVec2f.i
@@ -39,7 +39,7 @@ convert_SoMFVec2f_array(PyObject * input
 
 /* free the list */
 %typemap(freearg) const float xy[][2] {
-  if($1) delete[] $1;
+  if($1) free($1);
 }
 
 %typemap(in) const float xy[2] (float temp[2]) {
--- pivy-0.6.5.orig/Inventor/fields/SoMFVec3d.i
+++ pivy-0.6.5/Inventor/fields/SoMFVec3d.i
@@ -39,7 +39,7 @@ convert_SoMFVec3d_array(PyObject * input
 
 /* free the list */
 %typemap(freearg) const double xyz[][3] {
-  if ($1) { delete[] $1; }
+  if ($1) { free($1); }
 }
 
 %typemap(in) const double xyz[3] (double temp[3]) {
--- pivy-0.6.5.orig/Inventor/fields/SoMFVec3f.i
+++ pivy-0.6.5/Inventor/fields/SoMFVec3f.i
@@ -39,9 +39,10 @@ convert_SoMFVec3f_array(PyObject * input
 
 /* free the list */
 %typemap(freearg) const float xyz[][3] {
-  if ($1) { delete[] $1; }
+  if ($1) { free($1); }
 }
 
+
 %typemap(in) const float xyz[3] (float temp[3]) {
   convert_SbVec3f_array($input, temp);
   $1 = temp;
--- pivy-0.6.5.orig/Inventor/fields/SoMFVec4f.i
+++ pivy-0.6.5/Inventor/fields/SoMFVec4f.i
@@ -39,7 +39,7 @@ convert_SoMFVec4f_array(PyObject * input
 
 /* free the list */
 %typemap(freearg) const float xy[][2] {
-  if ($1) { delete[] $1; }
+  if ($1) { free($1); }
 }
 
 %typemap(in) const float xyzw[4] (float temp[4]) {
--- pivy-0.6.5.orig/Inventor/nodekits/SoBaseKit.i
+++ pivy-0.6.5/Inventor/nodekits/SoBaseKit.i
@@ -2,6 +2,8 @@
 %extend SoBaseKit {
 %pythoncode %{
     def __getattr__(self,name):
+       if name == 'this':
+          return SoNode.__getattr__(self,name)
        c = _coin.SoBaseKit_getNodekitCatalog(self)
        if c.getPartNumber(name) >= 0:
            part = self.getPart(name,1)
--- pivy-0.6.5.orig/interfaces/coin.i
+++ pivy-0.6.5/interfaces/coin.i
@@ -28,6 +28,10 @@ applications."
 // https://stackoverflow.com/questions/40959436/swig-python-detected-a-memory-leak-of-type-uint32-t-no-destructor-found
 %include "stdint.i"
 
+%begin %{
+#define PY_SSIZE_T_CLEAN
+%}
+
 %{
 #if defined(_WIN32) || defined(__WIN32__)
 #include <windows.h>
@@ -95,15 +99,11 @@ if (init_file_emulator() < 0) {
 */
 
 %pythoncode %{        
-for x in list(locals()):
-  value = locals()[x]
-  try:
-    if isinstance(value, type) and issubclass(value, SoFieldContainer):
-      for name in list(value.__dict__):
-        val = value.__dict__[name]
-        if isinstance(val, property):
-          delattr(value, name)
-  except NameError:
-    # value == SoSearchAction_duringSearchAll ???
-    pass
-%}
\ No newline at end of file
+for key in list(locals()):
+  x = locals()[key]
+  if isinstance(x, type) and issubclass(x, SoFieldContainer):
+    for name in list(x.__dict__):
+      thing = x.__dict__[name]
+      if isinstance(thing, property):
+        delattr(x, name)
+%}
--- pivy-0.6.5.orig/interfaces/coin_header_includes.h
+++ pivy-0.6.5/interfaces/coin_header_includes.h
@@ -352,6 +352,7 @@
 #include <Inventor/misc/SoGLBigImage.h>
 #include <Inventor/misc/SoGLImage.h>
 #include <Inventor/misc/SoGlyph.h>
+#include <Inventor/misc/SoGeo.h>
 #include <Inventor/misc/SoLightPath.h>
 #include <Inventor/misc/SoNormalGenerator.h>
 #include <Inventor/misc/SoNotification.h>
@@ -404,6 +405,10 @@
 #include <Inventor/nodes/SoFile.h>
 #include <Inventor/nodes/SoFont.h>
 #include <Inventor/nodes/SoFontStyle.h>
+#include <Inventor/nodes/SoGeoCoordinate.h>
+#include <Inventor/nodes/SoGeoLocation.h>
+#include <Inventor/nodes/SoGeoOrigin.h>
+#include <Inventor/nodes/SoGeoSeparator.h>
 #include <Inventor/nodes/SoGroup.h>
 #include <Inventor/nodes/SoImage.h>
 #include <Inventor/nodes/SoIndexedFaceSet.h>
--- pivy-0.6.5.orig/interfaces/pivy_common_typemaps.i
+++ pivy-0.6.5/interfaces/pivy_common_typemaps.i
@@ -28,19 +28,12 @@ typedef int Py_ssize_t;
   #define IS_PY3K
 #endif
 
-/* a casting helper function */
-SWIGEXPORT PyObject *
-cast(PyObject * self, PyObject * args)
+PyObject *
+cast_internal(PyObject * self, PyObject * obj, const char * type_name, Py_ssize_t type_len)
 {
   swig_type_info * swig_type = 0;
   void * cast_obj = 0;
-  char * type_name, * ptr_type;
-  int type_len;
-  PyObject * obj = 0;
-
-  if (!PyArg_ParseTuple(args, "Os#:cast", &obj, &type_name, &type_len)) {
-    SWIG_fail;
-  }
+  char * ptr_type;
 
   /*
    * add a pointer sign to the string coming from the interpreter
@@ -74,7 +67,24 @@ cast(PyObject * self, PyObject * args)
   if (SWIG_arg_fail(1)) { SWIG_fail; }
 
   return SWIG_NewPointerObj((void*)cast_obj, swig_type, 0);
-  fail:
+fail:
+  return NULL;
+}
+
+/* a casting helper function */
+SWIGEXPORT PyObject *
+cast(PyObject * self, PyObject * args)
+{
+  char * type_name;
+  Py_ssize_t type_len;
+  PyObject * obj = 0;
+
+  if (!PyArg_ParseTuple(args, "Os#:cast", &obj, &type_name, &type_len)) {
+    SWIG_fail;
+  }
+
+  return cast_internal(self, obj, type_name, type_len);
+fail:
   return NULL;
 }
 
@@ -86,18 +96,15 @@ autocast_base(SoBase * base)
 
   /* autocast the result to the corresponding type */
   if (base && base->isOfType(SoFieldContainer::getClassTypeId())) {
-    PyObject * cast_args = NULL;
     PyObject * obj = NULL;
     SoType type = base->getTypeId();
 
     /* in case of a non built-in type get the closest built-in parent */
     while (!(type.isBad() || result)) {
       obj = SWIG_NewPointerObj((void*)base, SWIGTYPE_p_SoBase, 0);
-      cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
       
-      result = cast(NULL, cast_args);
+      result = cast_internal(NULL, obj, type.getName().getString(), type.getName().getLength());
 
-      Py_DECREF(cast_args);
       Py_DECREF(obj);
 
       if (!result) { type = type.getParent(); }
@@ -120,18 +127,15 @@ autocast_path(SoPath * path)
   
   /* autocast the result to the corresponding type */
   if (path) {
-    PyObject * cast_args = NULL;
     PyObject * obj = NULL;
     SoType type = path->getTypeId();
 
     /* in case of a non built-in type get the closest built-in parent */
     while (!(type.isBad() || result)) {
       obj = SWIG_NewPointerObj((void*)path, SWIGTYPE_p_SoPath, 0);
-      cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
       
-      result = cast(NULL, cast_args);
+      result = cast_internal(NULL, obj, type.getName().getString(), type.getName().getLength());
 
-      Py_DECREF(cast_args);
       Py_DECREF(obj);
 
       if (!result) { type = type.getParent(); }
@@ -154,18 +158,15 @@ autocast_field(SoField * field)
 
   /* autocast the result to the corresponding type */
   if (field) {
-    PyObject * cast_args = NULL;
     PyObject * obj = NULL;
     SoType type = field->getTypeId();
 
     /* in case of a non built-in type get the closest built-in parent */
     while (!(type.isBad() || result)) {
       obj = SWIG_NewPointerObj((void*)field, SWIGTYPE_p_SoField, 0);
-      cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
       
-      result = cast(NULL, cast_args);
+      result = cast_internal(NULL, obj, type.getName().getString(), type.getName().getLength());
 
-      Py_DECREF(cast_args);
       Py_DECREF(obj);
       
       if (!result) { type = type.getParent(); }
@@ -188,18 +189,15 @@ autocast_event(SoEvent * event)
   
   /* autocast the result to the corresponding type */
   if (event) {
-    PyObject * cast_args = NULL;
     PyObject * obj = NULL;
     SoType type = event->getTypeId();
 
     /* in case of a non built-in type get the closest built-in parent */
     while (!(type.isBad() || result)) {
       obj = SWIG_NewPointerObj((void*)event, SWIGTYPE_p_SoEvent, 0);
-      cast_args = Py_BuildValue("(Os)", obj, type.getName().getString());
       
-      result = cast(NULL, cast_args);
+      result = cast_internal(NULL, obj, type.getName().getString(), type.getName().getLength());
 
-      Py_DECREF(cast_args);
       Py_DECREF(obj);
 
       if (!result) { type = type.getParent(); }
--- pivy-0.6.5.orig/interfaces/soqt.i
+++ pivy-0.6.5/interfaces/soqt.i
@@ -23,6 +23,9 @@ otherwise it will fall back to regular S
 
 %module(package="pivy.gui", docstring=SOQT_MODULE_DOCSTRING) soqt
 
+%begin %{
+#define PY_SSIZE_T_CLEAN
+%}
 
 %{
 /*
--- pivy-0.6.5.orig/pivy/graphics/__init__.py
+++ pivy-0.6.5/pivy/graphics/__init__.py
@@ -93,6 +93,7 @@ class Object3D(coin.SoSeparator):
     def drag_objects(self):
         if self.enabled:
             return [self]
+        return []
 
     def delete(self):
         if self.enabled and not self._delete:
@@ -454,4 +455,4 @@ class InteractionSeparator(coin.SoSepara
             else:
                 self.static_objects.append(child)
         else:
-            super(InteractionSeparator, self).addChild(child) 
\ No newline at end of file
+            super(InteractionSeparator, self).addChild(child) 

wmayer
Founder
Posts: 20303
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Current best practices to solve the 'pivy' problem?

Post by wmayer »

In case it's of interest here it was explained how to setup a local repository.

Setting up a local repository for Ubuntu 22.04 based on mini-dinstall is still very similar:
  • Install the package mini-dinstall
  • Create ~/.mini-dinstall.conf with this content (replace user with your real username)

    Code: Select all

    [DEFAULT]
    architectures = all, amd64
    archivedir = /home/user/public_html/debian
    use_dnotify = 0
    verify_sigs = 0
    extra_keyrings = ~/.gnupg/pubring.gpg
    mail_on_success = 0
    archive_style = flat
    poll_time = 10
    mail_log_level = NONE
    generate_release = 1
    
    [unstable]
    
    [jammy]
    
    
  • Create ~/public_html/debian/mini-dinstall
  • /etc/dput.cf should already contain

    Code: Select all

    [local]
    method                  = local
    incoming                = ~/public_html/debian/mini-dinstall/incoming
    run_dinstall            = 0
    post_upload_command     = /usr/bin/mini-dinstall --batch
    
  • Add this to /etc/apt/sources.list (replace user with your real username)

    Code: Select all

    deb file:/home/user/public_html/debian/jammy ./
    
In order to create a signed Debian package create a GPG key with

Code: Select all

gpg --gen-key
. Notice the name of the GPG key and the passphrase.

To sign the pivy package you can recreate it with

Code: Select all

debuild -kname_of_the_gpg_key
or you can sign the already created package with

Code: Select all

debsign pivy_0.6.5-1build7.dsc -kname_of_the_gpg_key
Afterwards the file can be uploaded to ~/public_html/debian with

Code: Select all

dput local pivy_0.6.5-1build7_amd64.changes
Issue: When updating your package index file with the APT tools you will get an error that the local repository is not signed. A workaround is to allow an insecure local repository which can be done with this line

Code: Select all

deb [allow-insecure=yes] file:/home/user/public_html/debian/jammy ./
I haven't figured out yet how to properly sign a local repository.
User avatar
iplayfast
Posts: 256
Joined: Sat Sep 07, 2019 6:55 am

Re: Current best practices to solve the 'pivy' problem?

Post by iplayfast »

Does this fix the

Code: Select all

Show.ShowUtils.is3DObject error: module 'pivy._coin' has no attribute 'delete_SoGeo'
problems I've been having?

I was unsure of what to use from the github repository, so I took your patchs, and created a patch.txt (vague memory of using this 2 decades ago).

something like
patch <patch.txt
but then it asks me what file to patch and I'm stuck.

I have tried installing the github pivy using make install (previously)
But that was probably not the best solution.
User avatar
dpward
Posts: 27
Joined: Sun Jan 01, 2023 6:06 pm
Contact:

Re: Current best practices to solve the 'pivy' problem?

Post by dpward »

Fix released for pivy in Ubuntu 22.04 LTS (and Ubuntu 22.10).
https://bugs.launchpad.net/ubuntu/+sour ... ug/2000840
Post Reply