scribus.unGroupObject ... Look before you leap?

Previous topic - Next topic

Astroman Pete

I'm profiling some code using the stable Scripter, and I'm noticing that scribus.unGroupObject takes a while, about 400 milliseconds. This adds up really fast.

I'm working with groups of objects, and if I don't ungroup objects before deleting them... bad things happen. Is there a look-before-you-leap method to tell if an object is in a group. Is there a data structure I'm missing that lists the groups and members present in the current document?

Thanks!

a.l.e

hi pete,

there is getItemType(), but it seems to return a wrong value for groups.

all in all, please report a bug for the bad things happening (more details are needed!) on http://bugs.scribus.net!

finally, i think that you can easily browse through all the items in the document...

hth
a.l.e

Astroman Pete

Hello Sir,

Thanks for the reply.

I'm going to optimize this time around by making the assumption that my users won't change the group structure of the objects I'm handling. That's not a great long term solution, I'd like to be able to handle whatever the pesky users throw at me, but it'll tide me over until Scripter2 stabilizes.

If I do a scribus.deleteObject on an object that belongs group, the page doesn't redraw (not even the guides); Even when the file is saved and re-opened.

I'm developing on Windows here at work. I plan on compiling a Scribus from SVN with Scripter 2 at home on my Ubuntu box to begin porting my work over to the new system. I'll check if these API calls are as expensive, and how they scale, in the new system also before filing any bugs.

a.l.e

nice, thanks!

i really hope that a usable scribus 1.5svn + scripter 2 is only a few month away!

for now it's not meant for production, but with a bit of luck we are very close to have it usable.
cezaryace and chelen are making wonders!

ciao
a.l.e

Astroman Pete

Just to follow-up:

This code snippet will parse the current file's XML to give you a dictionary of groups in the document. Something similar could be done to get other information difficult to find in Scripter, like the current page's Master page. This has the overhead of saving the file, of course.


from xml.etree import ElementTree as ET

scribus.saveDoc()
tree = ET.parse(scribus.getDocName())
objects = tree.findall('DOCUMENT/PAGEOBJECT')
groups = {}
for obj in objects:
    if "ANNAME" in obj.attrib and "GROUPS" in obj.attrib:
        for g in obj.attrib['GROUPS'].split(' '):
            if g in groups.keys():
                groups[g].append(obj.attrib['ANNAME'])
            elif g != '':
                groups.update({g:[obj.attrib['ANNAME']]})


This is off topic, let me know if I should start a new thread, but it appears that my application may be much faster if I closed the file in Scribus, manipulate the SLA file, then reopen it. This approach seems to work okay in Inkscape. I know the file format is in flux, as well.

It may have big performance benefits. I'm wrangling hundreds of objects. It would also have the benefit of being able to do updates/queries "gui-less", in cronjobs and what not.

The DTD in the 1.4 branch of the Subversion tree doesn't look like the files 1.4.2svn creates. Is this going to change before 1.4.2 is released?
http://scribus.net/websvn/filedetails.php?repname=Scribus&path=%2Fbranches%2FVersion14x%2FScribus%2Fdtd%2Fscribus.dtd


I found this page on the current format.  http://wiki.scribus.net/canvas/File_Format_Specification_for_Scribus_1.4#Scribus_Objects_.28SCE.29

I guess my question is, "Is it advisable to interface with the SLA file format, or is it too unstable?"

a.l.e

hi pete,

personally, i would not invest to much time in hacking scripts that modify the .sla files directly.

except if that solves a specific problem for one of your projects :-)

i think that the good way would be to add the missing item or even optimize the scripter API.
if you really need it NOW make patches for 1.4 and the current scripter... if it's for future use do it for 1.5svn and the new scripter.

if you need help, just ask!
ciao
a.l.e

Astroman Pete

#6
I will heed your advice.

Sorry I went quiet for a little bit. I was working on the parts of my application that don't interact with Scribus.

I hope you don't mind if I prattle on a bit about what I've been working on:

I'm a technician in a small Architecture & Structural Engineering firm. In the spring, during a large project (100+ 30"x42" drawings sheets, which is very large for us), we found that AutoCAD's sheet layout functionality was not scaling well at all. It has several limitations, opportunities for human error, and has several redundant steps... and it's slow!

My application has three major parts:

The CAD facing part looks for anchor frames in the CAD files and writes them to Postscript files, and keeps a log of the production information in a Sqlite database.

The next component fills in Titleblock information for the user, based on the names and locations of polygons found on the master page. This works quite well. There's only two things that need improvement: Right now everything is tracked by object name, it'll be more appropriate to use PageItemAttributes. Also, there's a bug that keeps master page modifications made by Scripter from showing up until the document is closed and re-opened. Document-wide fields are filled-in and coordinated on every sheet, currently.

The last component places, updates and labels the Postscript tiles. Generating and formatting the  labels for these is getting awfully slow with the current Scripter. (6 seconds per tile) It's not really important that the drawing labels and references live in Scribus. I was thinking today that I should use Qt's QPainter class to simply draw these on the Postscipt files. That's a much better solution than trying to shoehorn them into the SLA file.

Notes on the attached images:

"screenshot1.png" shows a test sheet with a few drawings imported and the titleblock filled-out.

"screenshot2.png" shows a Titleblock dialog.

"callgraph.png" shows the greediest functions in the routine that updates the drawing tiles. All of the "new_func" blocks are inside of decorators,  so they are inconsequential.

"runsnake.png" shows the same profile inside of "Run Snake Run". The highlighted areas are three "scribus.unGroupObject" calls.

"ungrouping_times.png" shows a quick graph of how long it took to ungroup a given number of rectangles. It is curve does accelerate, as I expected, but 99 objects @ 0.88 seconds doesn't come near the 3 seconds I was seeing with far fewer objects. Perhaps this is related to the number of other groups in the drawing. I will tinker further, but first I think I will explore QPainter's Postscript capabilities.

[attachment deleted by admin]

a.l.e

hi!

i didn't 100% get what you are doing but it looks cool! :-)

i have some general comments... i'm managing the integration of the new scripter engine in scribus 1.5svn and i'm really wondering if you shouldn't rather target the new version instead.

if you're the only one using your scripts and having to open the .sla you're producing i think that it could be ok...

on the one side, you could take profit of all the improvements hennings and jain have put in there, on the other side you could contribute your changes in the new scripter and and contribute in that way to the advancement of scribus.
(if everything goes well, the current scripter won't be distributed with the future scribus 1.6... and the scripts written for 1.6 will be very different than the ones written for 1.4).

it's up to you to chose but, depending on the aim of your project it would be interesting to get you to test throughly the new scripter!

have a nice evening
a.l.e

Astroman Pete

Yep. I'm definitely planning to rewrite the code that interacts with Scribus to target the new Scripter. When that happens is a bit up in the air. I'm developing in Windows, and compiling the development branch in Windows is daunting (not that I've tried). I'm planning on making a version with the basic features, use it on a couple small projects myself to form an opinion about the workflow it supports, then document that basic version and distribute it to my co-workers.

After that, the first thing I'll do is target Scripter2. I also want to enable more input sources than AutoCAD, like FreeCAD and LibreCAD (if/when LibreCAD gets a scripting interface). Bricscad would be easy on Windows, because the ActiveX interface is the same. I believe I'd have to write something in Lisp for Bricscad on Linux.

I also want to share this under the GPL, but that decision is up to my employers.