KPovModeler Tutorial
Andreas Zehender
zehender at kde.org
Sat Jul 12 16:15:52 CEST 2003
Hi Hugo!
As promised here the tutorial:
One of the best example for all following sections is the class PMBox. Maybe
you should look at this class while reading the tutorial.
All POV-Ray objects are subclasses of the class PMObject. PMObject and
PMComposite object implement the basic functionality for hierarchies of
objects with references to siblings, children and parent objects.
Basic class attributes and information:
-----
There are two methods that provide basic class information:
1) PMObject::description( ): A translated description of the object
2) PMMetaObject* PMObject::metaObject( );
The class PMMetaObject holds all information about the class:
- The class name
- The class hierarchy (a pointer to the meta object of the parent class)
- A factory method to create a new instance, of the information that this
class is an abstract class
- A list of properties, to get and set attributes by name
Undo redo information
-----
PMObject has a virtual method createMemento, that creates by default an
instance of the PMMemento class. A memento holds all changed attributes of
one owner object.
All set methods have this format
if( newValue != m_oldValue )
{
if( m_pMemento )
m_pMemento->addData( pointerToTheMetaObject, someID, m_oldValue );
m_oldValue = newValue;
}
The combination <metaObject, ID> has to be unique and identifies the
attribute. This way you don't have to know which IDs are used in base
classes.
When an object has to be changed, for example by an object properties view,
first PMObject::createMemento is called.
Then the objects attributes are changed. The old values of changed attributes
are now stored in the memento.
Then the properties view takes the memento with PMObject::takeMemento and
creates a PMDataChangeCommand for undo/redo.
If an old state should be restored, PMObject::restoreMemento is called.
PMBox::restoreMemento iterates over all stored values, ignores all values that
have a pointer to another meta object (and therefore are values of other
classes in the hierarchy) and restores all own attributes.
Then it calles restoreMemento for the base class.
Serialization
-----
All data is stored as xml. Loading and saving objects is quite simple with the
Qt xml classes
Just look at PMBox::serialize and PMBox::readAttributes.
Representation in the properties view
-----
The class PMDialogEditBase is the base class for all widgets in the properties
view. PMObject has a factory method PMObject::editWidget to create the
correct edit widget.
There is a corresponding edit widget for (almost?) all objects.
PMDialogEditBase has these important methods:
1. createTopWidgets and createBottomWidgets.
These two methods specify the order in which widgets of all classes in the
hierarchy are arranged.
createTopWidgets first calls the implementation of the base class and then
creates widgets for the own attributes.
createBottomWidgets first creates widgets and then calls the implementation of
the base class.
This leads to the followind order for PMBox:
topWidgets (PMObject)
topWidget (PMCompositeObject)
topWidget (PMNamedObject)
topWidget (PMSolidObject)
topWidget (PMGraphicalObject)
topWidgets (PMBox)
bottomWidgets (PMBox)
bottomWidgets (PMGrahicalObject)
bottomWidgets (PMSolidObject)
...
Edit widgets with important attributes that should be shown first create the
edits in createTopWidgets (like the name attribute in PMNamedObjectEdit),
objects with attributes that shouls be shown last create the widgets in
createBottomWidgets (like the switches in PMCompositeObject).
This way every edit widget has automatically the widgets of the base class
plus some own widgets.
2. displayObject
Displays the attributes of the current object
3. isDataValid
Validates the data and displays an error message if the user has typedin some
invalid data.
4. saveData
Saves the attributes in the edit widget to the displayed object.
5. The signal dataChanged
This signal should be emitted when a value was changed in some widget. There
are a number of widgets that implement this signal (PMIntEdit, PMFloatEdit,
PMVectorEdit ...)
Graphical representation:
-----
The class PMViewStructure represents the wire frame of an object. It contains
vertexes and connections and maybe later faces.
The view structure is create by PMObject::createViewStructure. This method is
called when the object should be rendered in the wire frame view and the view
structure is not up to date. To mark the view structure as invalid, call
setViewStructureChanged in a set method that changes the view structure
(PMBox::setCorner*)
To save memory, every class can have a default view structure that can be
shared between different instances.
Imagine a user, that creates a number of boxes and resizes the boxes only with
transformations and not with the corner attributes. Then all boxes have the
same view structure, both vertexes and lines.
And even when the user changes the corner attributes, the information which
vertexes are connected to each other can be shared, as it is the same for all
boxes.
PMObject::defaultViewStructure returns the default view structure, if any
exists. This view structure is automatically used if PMObject::isDefault
returns true.
In PMBox::createViewStructure you can see, how the line information is shared.
The class PMControlPoint represents a control point in the wire frame. With
control points the user can change object attributes in the wire frame view.
There is one control point class for every type or behavior of control
points.
PMObject::controlPoints creates the control points for the object
PMObject::controlPointsChanged take the control point attibutes to synchronize
them with the objects attributes.
Object hierarchies
-----
There is a rule based system (PMInsertRuleSystem) that determines which object
can be inserted into another object at which position.
The rules are described in baseinsertrules.xml.
There is a dtd with some basic description of the tags.
I think the tags are self-explanatory.
POV-Ray IO
-----
POV-Ray output is located in PMPovray31Format and pmpovray31serialization.*
The serialization methods use a class named PMOutputDevice that handles
indentation.
The important methods are
objectBegin
writeLine
objectEnd
The scanner and parser is maybe a bit difficult to understand. Just look at
some parse methods for different objects.
So far the basic tutorial.
If you have questions, just ask here on the list.
Andreas
--
--------------------------------------------------
Andreas Zehender
Master of Computer Science, Dipl. Ing. (BA)
http://www.azweb.de
az at azweb.de | zehender at kde.org
--------------------------------------------------
More information about the kpovmodeler-devel
mailing list