[vtk-developers] Class design for spline visualizations

Lin M majcjc at gmail.com
Thu Jun 18 21:17:15 EDT 2015


Sorry...

The vtkControlPointArray is the subclass of vtkMappedDataArray. I define a
variable to indicate that the begin idx of the patch which I assume will be
set when vtkBezierPatchAdaptor::Next() or vtkBezierPatchAdaptor::GoToPatch()
is called.

On Thu, Jun 18, 2015 at 9:11 PM, David Thompson <david.thompson at kitware.com>
wrote:

> Hi Lin,
>
> It looks like you forgot to add the header and implementation files to the
> commit.
>
>         David
>
> > On Jun 18, 2015, at 9:08 PM, Lin M <majcjc at gmail.com> wrote:
> >
> > Hi Dr. Thompson,
> >
> > I have added one commit which contains a vtkMappedDataArray subclass but
> I'm not sure I totally get the idea about the in-situ data structures. Can
> you take a look at it please? (
> https://gitlab.kitware.com/splines/vtk/merge_requests/4)
> >
> > Best,
> > Lin
> >
> > On Thu, Jun 18, 2015 at 10:47 AM, David Thompson <
> david.thompson at kitware.com> wrote:
> > Hi Lin,
> >
> > > From some examples I saw, usually we put some points in vtkPoints,
> store the connectivity in cellArray and add them to a dataset (vtkPolyData,
> vtkStructuredGrid or vtkUnstructureGrid). So is that we store the control
> point of multiple patches in the vtkPoints where we replace the
> vtkDataArray with vtkMappedDataArray now? And in a vtkMappedDataArray, we
> store all the points for all patches together but we overwrite how to
> iterate the array.
> >
> > That is nearly correct. We will accept
> >
> >     vtkDataObject* ControlPointData;
> >
> > from the user. For the case we will implement first, ControlPointData's
> actual type will be the vtkStructuredGrid subclass of vtkDataObject. The
> vtkStructuredGrid instance can hold many user-supplied vtkDataArray
> instances:
> >
> >     vtkStructuredGrid* structuredControlPoints =
> >       vtkStructuredGrid::SafeDownCast(ControlPointData);
> >
> >     // Control points to map from parameter-space to world coordinates:
> >     vtkDataArray* geometricControlPoints =
> >       structuredControlPoints->GetPoints()->GetData();
> >
> >     // Control points to map from paramter-space to scalar fields:
> >     vtkDataSetAttributes* scalarFields =
> structuredControlPoints->GetPointData();
> >     vtkIdType numScalarFields = scalarFields->GetNumberOfArrays();
> >     for (vtkIdType i = 0; i < numScalarFields; ++i)
> >       { // scalarFieldControlPoints will hold things like temperature,
> pressure, etc.:
> >       vtkDataArray* scalarFieldControlPoints = scalarFields->GetArray(i);
> >       }
> >
> > Because the user supplies these arrays, we cannot force them to be
> vtkMappedDataArray. Instead, we can make a vtkMappedDataArray subclass that
> owns a reference to one of the arrays above and only returns one patch's
> values from the user-supplied array (which holds the values for all patches
> in the spline).
> >
> > The BezierPatchAdaptor below would return instances of our
> vtkMappedDataArray when its GetPatchPoints method is called. Now that I've
> written some more out, it looks like the API should be changed a little bit
> so that users can ask for a particular array (geometricControlPoints or
> scalarFieldControlPoints):
> >
> > class vtkBezierPatchAdaptor : public vtkObject
> > {
> > public:
> >   virtual void SetControlPointData(vtkDataObject* controlPointData);
> >   vtkGetObjectMacro(vtkDataObject,ControlPointData);
> >
> >   // Methods to iterate over patches:
> >   // ... same as below ...
> >
> >   // Methods to access the current patch:
> >   // ...
> >   virtual vtkSmartPointer<vtkMappedArray> GetPatchPoints(int
> scalarField) const = 0;
> >   // ...
> > };
> >
> > This way, GetPatchPoints() could return the vtkMappedDataArray for
> geometricControlPoints when the "int scalarField" argument is negative
> value and a vtkMappedDataArray for one of the scalarFieldControlPoints
> arrays when scalarField is positive.
> >
> > Having GetPatchPoints() return a smart pointer to a vtkMappedDataArray
> subclass would also get around the issue that vtkPoints expects its
> vtkDataArray to have 3 components per tuple (where ours will have 4 for
> geometricControlPoints or an arbitrary number for scalarFieldControlPoints).
> >
> > The vtkMappedDataArray instances would own a weak reference back the
> vtkBezierPatchAdaptor which created them and a weak reference to the
> geometricControlPoints or scalarFieldControlPoints array it draws values
> from. When vtkBezierPatchAdaptor::Next() or
> vtkBezierPatchAdaptor::GoToPatch() is called, the adaptor would iterate
> over all of the vtkMappedDataArray instances it owns and change an internal
> variable so they would return values for the proper patch. That way the
> vtkMappedDataArray instances only have to be created once for each spline
> dataset, not once per patch.
> >
> > Is that clear enough, or should I sketch out a header file for our
> vtkMappedDataArray subclass?
> >
> >         David
> >
> > > On Wed, Jun 17, 2015 at 10:22 PM, David Thompson <
> david.thompson at kitware.com> wrote:
> > > Hi Lin,
> > >
> > >> Sorry for late reply. Since the midterm is coming, I'll definitely
> speed up the development from now on.
> > >
> > > We both need to do a little more work. I have been looking at how to
> read data from PetIGA so we can show some actual simulation data and have
> some 3-D volumetric examples.
> > >
> > > It would be nice to have a patch ready to merge into VTK's master
> branch at the midterm that provides spline interpolation and tests it for
> all 3 parametric dimensions (curves, surfaces, and volumes). The means
> producing triangles and tetrahedra, not just polylines.
> > >
> > >> 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.
> > >
> > > Close. I think that we should use the vtkMappedDataArray class to hold
> control points for multiple patches but program it to appear as if points
> for each individual patch are stored in patch-order.
> > >
> > >> Do you mean store multiple vtkDataArray regarding to multiple patches
> in the vtkDataObject?
> > >
> > > There would be one data array to hold point coordinates, but other
> arrays would hold simulation variables like temperature, pressure,
> velocity, and so on.
> > >
> > >> If so, what class do I need to use for vtkDataObject?
> > >
> > > The class outline below is an abstract class. A concrete
> implementation for NURBs would require   the base class's ControlPointData
> to be an instance of vtkStructuredGrid. A T-spline implementation might
> expect ControlPointData to be a vtkUnstructuredGrid. I think all we should
> do this summer is the NURBs case.
> > >
> > >     David
> > >
> > >>
> > >> 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/20150618/f7383414/attachment-0001.html>


More information about the vtk-developers mailing list