[PythonCAD] other notes about development

Art Haas ahaas at airmail.net
Mon Jun 20 17:55:19 CEST 2005

On Mon, Jun 20, 2005 at 01:03:32PM +0200, Rafael Villar Burke wrote:
> Art Haas wrote:
> > [ ... snip ... ]
> I also don't think having commit access to a repository is so important. 
> Subversion is quite easy to use and install in a lot of platforms, and 
> while a distributed model would make much easier having local branches 
> to hack on, there isn't still (IMHO) a good enough replacement to be 
> used in PythonCAD. Furthermore, using git comes with the drawback of not 
> being able to contribute if you work on win32, and, I'd dare to say that 
> most people working on professional CAD are tied to the win32 platform 
> (exceptions are numerically irrelevant, AFAICT). This will be a big 
> point for the adoption of PythonCAD and make the switch, and loosing so 
> many potential contributors now would be a big error, IMHO.
I've not commited myself to switching to 'git' yet, and any change that
would it harder for people to someone to contribute to PythonCAD I want
to avoid. Making the master code repository public could entice more
people to help out, but there is no guarantee that will happen.

> If it is of any help, I've been tracking the development some SCM 
> systems, and I look with great curiosity and hope the ongoing work on 
> Mercurial (http://www.selenic.com/mercurial/) and Bazaar-NG 
> (http://bazaar-ng.org/). Both are written in python, are easy to use, 
> don't have complicated dependencies (bazaar-ng only requires python) and 
> are being heavily developed. The sad part is that, despite they are 
> self-hosting and usable, they are still not mature to be used in 
> production work AFAICT...

I've seen a bit about Mercurial when I read the 'git' development list,
but not much about Bazaar-NG. 

> > [ ... snip ... ]
> >
> >I've hoped that people sharing your view above - the existing tools are
> >not adequate or nonexistant - would find PythonCAD and want to
> >contribute. I know that there is a demand for CAD software on Linux and
> >the BSD varieties, and that a good CAD package would fill a missing niche 
> >in the current software offerings. Making the CAD package open-source
> >means it could run on platforms that commericial packages would not
> >consider. Closed-source CAD would probably not run on older releases of
> >Fedora/RedHat, Suse, Mandrake/Mandrive, etc, or on PPC/Alpha/Sparc
> >chips, and probably not on older BSD releases either.
> >  
> >
> A lot of people would like to make the switch to a free and powerful CAD 
> tool, but take into consideration that besides changing aplications, in 
> most cases it's also a change in platform. Most people to whom I have 
> shown PythonCAD really appreciate being able to test it on Windows, even 
> when installing pythoncad, through gtk+, pygtk and python is not as easy 
> as any other windows app. Besides the installation burden, I think 
> having a closs platform app is a killer feature for PythonCAD, as well 
> as being written in python (easy to hack, no compiles...).

I realize that many potential PythonCAD users are currently not using
Linux/BSD, so having them switch from their current CAD package will
not be easy. The fact that PythonCAD is somewhat cross-platform is
certainly a plus, and the points you make about Python itself are
definitely true.

> >>partitioning the problem
> >>  (too many cooks don't fit in one bowl of soup)
> >>  This is big architectural step-back and chin-scratch type of stuff.
> >
> >The lack of cooks is something I want to change. :-)
> >
> I believe that having some more short term goals and concentrate on 
> users, not only on developers could be beneficial to have some more 
> exposure an attract new developers too. QCad did concentrate on being 
> usable to make furniture drawings, or basic geometrical shapes, etc and 
> that's why I think there are some free electronic cad programs around 
> with relative success. Users would bring some more feedback and more 
> rewarding short term goals (I admire you for being able and have the 
> will to keep it going, really!).

I'd love to get more feedback from users, especially on the mailing
list. Comments posted to the list can produce replies from many people,
as well act as an encouragement to try new approaches in resolving the
questions/problems in the original message.

> Another point I humbly think makes difficult to grow a community of 
> developers is that some architectural decisions such as the generic UI 
> layer, which were made to have some more flexibility in the future, make 
> current development too complex and burdensome. The current situation 
> makes difficult to take advantage of the underlaying toolkit 
> capabilities and to attract developers that are proficient in a specific 
> toolkit.
>  I'd rather go for a gtk+ interface and avoid having to learn another 
> GUI model and its API, as I hope the ongoing Cairo integration can get 
> us the benefit of easy printing, an usable canvas, so much needed for 
> graphical apps such as PyhtonCAD.

As the GTK+ interface is currently the only active interface being
developed, somewhat to my disappointment, there can be a case made that
the design of the program discourages developers. If PythonCAD was to
solely be a PyGTK/GTK+ program then the generic messaging system could
be replaced with Glib's gobject signal approach. I still believe that in
the long run seperating the program into an interface-neutral core and 
interface-specific UI is the best approach for development. Some of the
missing features in the standard PyGTK/GTK+ are made visible - printing
for example - where in other environments like PyQT/PyKDE there is built
in functionality for printing. If a single person or group decided to
contribute a PyQT/PyKDE front end I would do everything I could to make
things easy for him/her/them to contribute and maintain that code, plus
I am certain the new code would expose weakness in the core code that,
once made visible, could be rectified. The end result is a better program
all around, regardless of the interface.

> >
> >>write a HACKING howto
> >>  I've had a lot of things that I would like to fix in KDE, but would 
> >>need to spend the better part of a few days figuring out how to 
> >>checkout and setup a development copy of it without screwing up my 
> >>production environment (might even take that long _with_ a HACKING 
> >>howto!)
> >
> >This could certainly be done.
> >
> Apart from this good idea, I'd add having a visible TODO list. A list of 
> tasks of varying difficulty, size, and nature (documentation, webdesign, 
> coding, advocacy...). A list of tasks makes easy to contribute, as you 
> don't need to know what's going on to be able to help, and you can see 
> if there are some tasks that suit your time and knowledge. I've had the 
> experience of seeing how little but interesting tasks were being made by 
> casual developers that spent a couple of hours hacking on a project 
> (gazpacho) because it was easy to do it thanks to an appealing TODO list.

I'll add a 'TODO' file in the next release.

> > [ ... snip ... ]
> >
> >The program still lacks numerous features that make using it on a daily
> >basis not feasible. Hatching, for one, is essential in any cad package,
> >and PythonCAD doesn't offer this necessary feature. The lack of a
> >spline-type entity is also a shortcoming, and I am certain that other
> >people have various entities they use in CAD software that PythonCAD
> >currently lacks.
> >
> >I'm all for hearing some rants about PythonCAD and its shortcomings. My
> >skin is pretty thick, and I have no doubt that the program is lacking in
> >numerous areas. To get things started, here are a few problems that
> >irritate me ...
> >
> >1) No hatching, ellipse, spline/nurbs entities. The lack of these
> >entities make drawing curved objects really difficult.
> >  
> >
> I don't think these are _really_ so important. PythonCAD is not suited 
> now (and won't be in a while) to do high precision jobs... and any of 
> these can be done using arcs and lines with reasonable good results. 
> Well, maybe I'm too biased towards construction, architecture and 
> engineering drawing...

My background is mechanical engineering, so I may share some of those
biases. The first company I worked for after leaving college made oil
field equipment, and there were a few times that ellipse and spline
entities were in the drawings. Hatching, though, was essential. For
people doing architectural drawings I'd imaging hatching and splines
would be common.

> >2) No import/export abilities. DWG/DXF in particular.
> >
> This is really important... if you have a good exporter you can overcome 
> the app's shortcomings using other apps to do the work.

The ability to import an existing drawing into PythonCAD is essential,
and ideally this should be transparent to the user. Exporting can be
done by saving the file in the normal XML format and then a stand-alone
converting utility be invoked, but it would be really nice to save
directly into the desired format.

> >3) No ability to easily create, save, and load user-defined linetypes
> >and styles. These things could be done by hacking on the code, but that
> >is not realistic for most uses.
> >  
> >
> A dashed line, a dash-dot line for axes, and a continuous line should be 
> enough for basic usage.

These linetypes are in the program now, but I want to make it easy for
people to define their own linetypes and styles if they wish. This
feature though is a lower priority than others listed here.

> >4) Drawing behavior - by this I mean the GTK calls to draw in the
> >DrawingArea. All entities are redrawn far too often, drawing dimensions
> >leaves ghosted or hidden lines, zooming only done with menu choices,
> >no keyboard abilities to pan left, right, up, down.
> >  
> >
> More GUI and usability work would be great... making some things but 
> doing them really well is the basis for further steps, IMHO. Maybe we 
> are stuck now waiting for easier solutions to come with cairo 
> integration into gtk+ (I can't see the time where gtk+ gets a first 
> class retained mode drawing widget!), so perhaps this work will be 
> easier later on...

Over the last couple of days I've been adding code to the core files
which will help with drawing. A short discussion at the end of message
will follow.

> >5) Limited documentation for the various entities and no tutorial for
> >users wanting to try the program for the first time.
> >
> This has the benefit of realizing what parts are missing, as you have to 
> take the position of a user who wants to achieve concrete tasks.

Anyone care to start a PythonCAD documentation project? :-)

> >I've been working on problem #4 above. My approach to solving many of
> >these problems is to utilize the 'ImageView' class in 'gtkshell.py'.
> >The goal would be to replace the DrawingArea instance in 'gtkimage.py'
> >with an ImageView instance. The ImageView would utilize the messaging
> >abilities of the various entities and erase and redraw the entities
> >as needed. Adding a new entity to a drawing would no longer redraw
> >everything, and removing an entity would be done by redrawing it
> >but in the background color, again a single draw operation. The
> >ImageView would also respond to arrow key press events, and with
> >a little more cleverness, mouse wheel events. Unfortunately things have
> >been moving very slowly lately, so the current code still uses the
> >existing routines.

The changes in the last few days utilize two new messages
'change_pending' and 'change_complete'. The 'change_pending' message
is sent in the startChange() method, and 'change_complete' in, oddly
enough, endChange().

Here's an example of how they are used. The simplified setThickness()
routine again is useful, and here is how it had been written:

	setThickness(self, t):
		_ot = self.__thickness
		if abs(_ot - t) > 1e-10:
			self.__thickness = t
			self.sendMessage('thickness_changed', _ot)
			self.modified() # sends 'modified' message

So, when some entity has the thickness adjusted, the 'thickness_changed'
message goes out, then 'modified' is sent. Notice all these messages happen
after the actual value is changed. So, if my plans are to erase the
entity and redraw it with the new thickness, I'd have to listen for
'thickness_changed' messages, and when receiving that message use the
old value to perform the erase operation, then perform the draw with
the newly adjusted thickness. This is simple enough, but consider that
there are many entity types, and complex entities like dimensions send
out many different messages regarding changed values. It would become
a maintenence nightmare trying to listen for all the different 'changed'
type messages.

Here is how things now look with the startChange() and endChange()

	setThickness(self, t):
		_ot = self.__thickness
		if abs(_ot - t) > 1e-10:
			self.__thickness = t
			self.sendMessage('thickness_changed', _ot)
			self.modified() # sends 'modified' message

The startChange() call sends the 'change_pending' message, as well as
the message the object will send once the change is complete. What the
program will listen for initially is just the 'change_pending' message.
So, when receiving this message, the entity is still in its unchanged
state, so the erase() operation can be performed while the entity values
match what the last draw() operation saw, so erasing the object from the
image should not leave any ghost pixels. The big win, however, is that
the program only needs to listen for 'change_pending' messages from
any entity instead of the many various 'changed' type messages. This
enormous simplification greatly eases the burden of handing erase
and draw operations.

The endChange() call currently is a complement to startChange(), but
I don't see it being used at first. It does offer a bit of info to
any object listening for 'change_complete' in that the entity sending
the message has finished adjusting whatever values were to be changed.

> A great thing of your release planning is always going forward and 
> concentrate on specific tasks, instead of continuously aiming at 
> perfection and running in circles... :)

A 'perfect' program would never get publically released, or privately

> >Rant away ...
> >  
> >
> After all... you're doing an incredibly good job, and I can't express 
> how bad I feel not being able to be more helpful. I've even tried to get 
> some institution and some people to work on PythonCAD development, but 
> I've seen that there's a vicious circle here... if it's not usable no 
> one uses it, so no feedback, and no external development happens...

The old chicken-and-egg problem in action ...

> Thanks for your work and your perseverance.


Man once surrendering his reason, has no remaining guard against absurdities
the most monstrous, and like a ship without rudder, is the sport of every wind.

-Thomas Jefferson to James Smith, 1822

More information about the PythonCAD mailing list