here's some followup on my meddling with nurbs:
I'v defined the following Path IDL:
typedef sequence<Vertex> Polyline;
struct Nurbs
{
unsigned short degree;
sequence<Vertex> controls;
sequence<double> weights;
sequence<double> knots;
};
enum PathSegmentType { polyline_t, nurbs_t};
union PathSegment switch (PathSegmentType)
{
case polyline_t: Polyline polyline_a;
case nurbs_t: Nurbs nurbs_a;
};
typedef sequence<PathSegment> Path;
Based on this, the code to define a path
looks so:
Path_var path = new Path;
path->length(4);
{
Polyline lines;
//... set vertices ...
path[0].polyline_a(lines);
}
{
Nurbs nurbs;
nurbs.degree = 3;
nurbs.controls.length(10);
//... set control points ...
nurbs.weights.length(10);
//... set weights ...
nurbs.knots.length(10 + 3 + 1);
//... set knots ...
path[1].nurbs_a(nurbs);
}
{
Polyline lines;
// and again ...
path[2].polyline_a(lines);
}
{
Nurbs nurbs;
//... and again ...
path[3].nurbs_a(nurbs);
}
which doesn't look that bad (IMO). All these calls
have to be made eventually, and there are basically
only two methods to access the sequences: 'length()'
and 'operator []'. How can you get simpler than that ?
Also note that the real work is the definition of the
individual segments. In this example I picked the two
extreme cases: a Polyline is the simplest path you can
concieve, and the nurbs is the most complex (read:
parameter-rich).
So if you would make Path an interface, you'd
basically
have to replace 'operator []' by real
accessor/manipulator
methods (at least an attribute).
As we discussed, there are arguments pro
interface, or better,
pro object. These are related to possibly adding a
'cachable'
interface, so we can track when the path was last
modified.
But just to be able to identify the path we could
probably
use a simple hash.
The real reason why I'm very reluctant to make
Path an interface
is that the Path is one of the most fine-grained
types (beside
basic types) we (will) use. And as I'm generally
tending to
think we should push CORBA out of the APIs, I
think this is
the level to start with. Location transparency is
good for
things such as models, callbacks, and to a certain
extend
graphics (though that's debatable), access to the
inner
structure of a path should be completely local.
CORBA has 'value types' offering an object model
that is
quite a bit more lightweight than that associated with
'CORBA objects', but it has other drawbacks. Not
sure I'd like
to start using yet another CORBA feature...
---
Some more arguments to the discussion related to
the CS,
i.e. the connection between adjacent segments:
PS uses a number of 'segment types' (to speak in
fresco
jargon): lines, arcs, curves. the definition of
the 'arc'
operator is such that it implicitely constructs a
line from
the current point to the starting point of the
arc, thus
breaking the simple 'moveto'/'lineto' paradigm you
seem so
fond of. Further, there is a 'lineto' and a
'rlineto', where
'rlineto' uses relative coordinates, so you can
effectively
append a line using the CS of the current point.
If we decide to use a similar approach, we could
stipulate three
possible 'connection methods':
* a new segment is added 'relatively' to the
current point,
i.e. make the starting point of the new segment
coincide
with the ending point of the last segment)
(which seems to me
semantically equivalent to 'rlineto')
* use an 'absolute CS' but implicitely connect the
adjacent end
points ('lineto')
* don't connect the segments ('moveto')
My impression is that postscript supports all
three ways, so I
don't see us 'breaking the rules' in any major way.
Oh, and I can see all three connection methods
being useful, so
I'd suggest that we add the ability to define that
(per segment)
to the path.
here's some followup on my meddling with nurbs:
I'v defined the following Path IDL:
typedef sequence<Vertex> Polyline;
struct Nurbs
{
unsigned short degree;
sequence<Vertex> controls;
sequence<double> weights;
sequence<double> knots;
};
enum PathSegmentType { polyline_t, nurbs_t};
union PathSegment switch (PathSegmentType)
{
case polyline_t: Polyline polyline_a;
case nurbs_t: Nurbs nurbs_a;
};
typedef sequence<PathSegment> Path;
Based on this, the code to define a path
looks so:
Path_var path = new Path;
path->length(4);
{
Polyline lines;
//... set vertices ...
path[0].polyline_a(lines);
}
{
Nurbs nurbs;
nurbs.degree = 3;
nurbs.controls.length(10);
//... set control points ...
nurbs.weights.length(10);
//... set weights ...
nurbs.knots.length(10 + 3 + 1);
//... set knots ...
path[1].nurbs_a(nurbs);
}
{
Polyline lines;
// and again ...
path[2].polyline_a(lines);
}
{
Nurbs nurbs;
//... and again ...
path[3].nurbs_a(nurbs);
}
which doesn't look that bad (IMO). All these calls
have to be made eventually, and there are basically
only two methods to access the sequences: 'length()'
and 'operator []'. How can you get simpler than that ?
Also note that the real work is the definition of the
individual segments. In this example I picked the two
extreme cases: a Polyline is the simplest path you can
concieve, and the nurbs is the most complex (read:
parameter-rich).
So if you would make Path an interface, you'd
basically
have to replace 'operator []' by real
accessor/manipulator
methods (at least an attribute).
As we discussed, there are arguments pro
interface, or better,
pro object. These are related to possibly adding a
'cachable'
interface, so we can track when the path was last
modified.
But just to be able to identify the path we could
probably
use a simple hash.
The real reason why I'm very reluctant to make
Path an interface
is that the Path is one of the most fine-grained
types (beside
basic types) we (will) use. And as I'm generally
tending to
think we should push CORBA out of the APIs, I
think this is
the level to start with. Location transparency is
good for
things such as models, callbacks, and to a certain
extend
graphics (though that's debatable), access to the
inner
structure of a path should be completely local.
CORBA has 'value types' offering an object model
that is
quite a bit more lightweight than that associated with
'CORBA objects', but it has other drawbacks. Not
sure I'd like
to start using yet another CORBA feature...
---
Some more arguments to the discussion related to
the CS,
i.e. the connection between adjacent segments:
PS uses a number of 'segment types' (to speak in
fresco
jargon): lines, arcs, curves. the definition of
the 'arc'
operator is such that it implicitely constructs a
line from
the current point to the starting point of the
arc, thus
breaking the simple 'moveto'/'lineto' paradigm you
seem so
fond of. Further, there is a 'lineto' and a
'rlineto', where
'rlineto' uses relative coordinates, so you can
effectively
append a line using the CS of the current point.
If we decide to use a similar approach, we could
stipulate three
possible 'connection methods':
* a new segment is added 'relatively' to the
current point,
i.e. make the starting point of the new segment
coincide
with the ending point of the last segment)
(which seems to me
semantically equivalent to 'rlineto')
* use an 'absolute CS' but implicitely connect the
adjacent end
points ('lineto')
* don't connect the segments ('moveto')
My impression is that postscript supports all
three ways, so I
don't see us 'breaking the rules' in any major way.
Oh, and I can see all three connection methods
being useful, so
I'd suggest that we add the ability to define that
(per segment)
to the path.
|