[vtk-developers] Class design for spline visualizations

Lin M majcjc at gmail.com
Wed Jun 17 21:11:42 EDT 2015


Hi Dr. Thompson,

Sorry for late reply. Since the midterm is coming, I'll definitely speed up
the development from now on. I have a question about the class design in
your last email. To my understanding, control points for one patch is
stored in a vtkDataArray. Do you mean store multiple vtkDataArray regarding
to multiple patches in the vtkDataObject? If so, what class do I need to
use for vtkDataObject?

Best,
Lin

On Wed, Jun 10, 2015 at 2:39 PM, David Thompson <david.thompson at kitware.com>
wrote:

> Hi Lin,
>
> > I have made it support 3D ellipse with function ...
>
> Great!
>
> > As you can see in the python test, I call this function 4 times for each
> quadrant to generate the entire ellipse. Since we need to support multiple
> patches, I think it's better to define a new dataset class for bezier
> patches as you mentioned before about  creating a new vtkControlPoints
> class that inherits from vtkPoints and allows for an extra coordinate.
>
> Rather than create new dataset types, I would like to use existing
> datatypes to store the data and make an adaptor to iterate over them. That
> way existing pipelines could modify scalar values defined on control points
> (and perhaps even patches). For instance, B-splines could be represented as
> a vtkStructuredGrid whose FieldData contains a special knot array (special
> in the sense that the array must be of the proper size and with a fixed
> name like "_vtkKnotVector").
>
> The adaptor would take a vtkDataObject as input and provide iterator-style
> access to each patch defined by the dataset. Specific subclasses of the
> adaptor would be B-splines (which expect the vtkDataObject to be a
> vtkStructuredGrid) or T-splines (which might expect a vtkUniformGridAMR) or
> even point-based splines (PB-splines as defined in Sederberg's T-spline
> paper, which could expect any dataset derived vtkPointSet).
>
> class vtkBezierPatchAdaptor : public vtkObject
> {
> public:
>   virtual void SetControlPointData(vtkDataObject* controlPointData);
>   vtkGetObjectMacro(vtkDataObject,ControlPointData);
>
>   // Methods to iterate over patches:
>   virtual void Begin() = 0;
>   virtual bool IsAtEnd() = 0;
>   virtual bool GoToPatch(vtkIdType patchId) = 0; // random access iteration
>   virtual bool Next() = 0;
>
>   // Methods to access the current patch:
>   virtual int GetPatchDimension() const = 0;
>   virtual void GetPatchShape() const = 0;
>     // returns VTK_TRIANGLE/VTK_QUAD when PatchDimension==2,
>     // returns VTK_HEXAHEDRON/VTK_TETRA when PatchDimension==3
>   virtual void GetPatchDegree(int* degreeOut) const = 0;
>   virtual void GetPatchParameterRange(double* paramsOut) const = 0;
>   virtual void GetPatchPoints(vtkPoints* pointsOut) const = 0;
>
>   // Some helper methods that would make Python wrappings usable:
>   int GetPatchDegree(int dim) const
>     {
>     std::vector<int> degree(this->GetPatchDimension());
>     this->GetPatchDegree(&degree[0]);
>     return degree[dim];
>     }
>   void GetPatchParameterRange(int dim, double paramRange[2])
>     {
>     std::vector<double> range(2 * this->GetPatchDimension());
>     this->GetPatchDegree(&range[0]);
>     paramRange[0] = [2 * dim];
>     paramRange[1] = [2 * dim + 1];
>     }
>
> protected:
>   vtkDataObject* ControlPointData;
> };
>
> The B-spline subclass could then iterate over patches by keeping a current
> "cell ID," which would be incremented by calling Next(). When asked for the
> *patch* points (not the input points), the adaptor would create a
> vtkMappedDataArray (see http://www.vtk.org/Wiki/VTK/InSituDataStructure
> for more information) that did not copy control point coordinates from its
> ControlPointData->GetPoints() but instead used the implicit connectivity to
> provide access to underlying B-spline points.
>
> For example, consider the simple case of a rectangular B-spline with
> degree 1 (bi-linear). We might be given a 5x6 grid of control points as
> input and asked to iterate over all the patches. Each patch is simply a
> quadrilateral, and there are (5-1)*(6-1) = 20 of them.
>
>   adaptor->Begin(); // would initialize an internal "cell ID" to 0
>   adaptor->IsAtEnd(); // would return false for "cell ID" values in [0,19]
> and true otherwise.
>   adaptor->GetPatchDimension(); // would return 2
>   adaptor->GetPatchShape(); // would return VTK_QUAD
>   adaptor->GetPatchDegree(degreeOut); // would populate degreeOut with
> [1,1]
>   adaptor->GetPatchPoints(pointsOut); // would populate pointsOut with a
> vtkMappedDataArray.
>
> The vtkMappedDataArray would report having 4 tuples (one for each corner
> of the quad... when the degree is higher, is would report the product of
> (degreeOut[i]+1) for all i in GetPatchDimension()). The actual points
> reported would depend on the "cell ID" in the adaptor.
>
> I have not figured out yet how the "w" homogeneous coordinate would work
> with vtkPoints. A different adaptor API might work better (keeping the "w"
> coordinate separate from the other points).
>
> > Another question is that currently the domain of parameter coordinate is
> [0, 1] for each patch. Do you think it's better to make the domain
> continuously, namely [0, 0.25] for the first quadrant, [0.25, 0.75] for the
> second quadrant, etc?
>
> If we focus on the B-spline adaptor above, we get that for free since the
> returned knot vector could be normalized to the range [0,1].
>
>         David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20150617/936f895d/attachment.html>


More information about the vtk-developers mailing list