Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

creating a Circle approximated by a BezierCurve #17

Closed
JHenneberg opened this issue Nov 9, 2021 · 7 comments
Closed

creating a Circle approximated by a BezierCurve #17

JHenneberg opened this issue Nov 9, 2021 · 7 comments
Labels
question Further information is requested

Comments

@JHenneberg
Copy link

I am struggling creating a BezierCurve. Could you give me an example how this is done?

@elrnv elrnv added the question Further information is requested label Nov 10, 2021
@elrnv
Copy link
Owner

elrnv commented Nov 10, 2021

Thank you for the question!
As far as I can tell Curve cells are relatively new in VTK and so there aren't many examples in the wild.
Though after digging through their documentation and examples, I discovered that you need a "RationalWeights" attribute for bezier curves. So something like the following should create a valid VTK file:

Vtk {
    version: Version { major: 4, minor: 2 },
    title: String::new(),
    byte_order: ByteOrder::BigEndian,
    file_path: None,
    data: DataSet::inline(UnstructuredGridPiece {
        points: IOBuffer::F64(vec![
            // coordinates of node 0
            0.0, 1.0, 0.0, // coordinates of node 1
            1.0, 0.0, 0.0, // coordinates of node 2
            1.0, 1.0, 0.0,
        ]),
        cells: Cells {
            cell_verts: VertexNumbers::Legacy {
                // Number of Bezier curves.
                num_cells: 1,
                // Vertices for each curve.
                vertices: vec![3, 0, 1, 2],
            },
            types: vec![CellType::BezierCurve],
        },
        data: Attributes {
            point: vec![Attribute::DataArray(DataArray {
                name: "RationalWeights".to_string(),
                elem: ElementType::Scalars {
                    num_comp: 1,
                    lookup_table: None,
                },
                data: vec![1.0f64, 1.0, 2.0f64.sqrt() / 2.0].into(),
            })],
            ..Default::default()
        },
    }),
}

For some references, there is a writeup about bezier curves used in VTK here and some example C++ code here which can be compiled and run to produce some .vtu examples. Here is one of a quadratic bezier generated by that code:

<?xml version="1.0"?>
<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
  <UnstructuredGrid>
    <Piece NumberOfPoints="3" NumberOfCells="1">
      <PointData RationalWeights="RationalWeights">
        <DataArray type="Float64" Name="RationalWeights" format="ascii" RangeMin="0.7071067811865476" RangeMax="1">
          1 1 0.7071067811865476
        </DataArray>
      </PointData>
      <CellData>
      </CellData>
      <Points>
        <DataArray type="Float32" Name="Points" NumberOfComponents="3" format="ascii" RangeMin="1" RangeMax="1.4142135623730951">
          0 1 0 1 0 0
          1 1 0
          <InformationKey name="L2_NORM_RANGE" location="vtkDataArray" length="2">
            <Value index="0">
              1
            </Value>
            <Value index="1">
              1.4142135624
            </Value>
          </InformationKey>
        </DataArray>
      </Points>
      <Cells>
        <DataArray type="Int64" Name="connectivity" format="ascii" RangeMin="0" RangeMax="2">
          0 1 2
        </DataArray>
        <DataArray type="Int64" Name="offsets" format="ascii" RangeMin="3" RangeMax="3">
          3
        </DataArray>
        <DataArray type="UInt8" Name="types" format="ascii" RangeMin="75" RangeMax="75">
          75
        </DataArray>
      </Cells>
    </Piece>
  </UnstructuredGrid>
</VTKFile>

It seems that these don't appear smooth in paraview though unfortunately. That may be a good question for the Kitware folks :)

Hope this helps and good luck!

@Andlon
Copy link
Collaborator

Andlon commented Nov 10, 2021

It seems that these don't appear smooth in paraview though unfortunately. That may be a good question for the Kitware folks :)

Yeah this is not so obvious, but there's a way to make them "arbitrarily" smooth. You need to toggle on "Advanced Properties" for the object. Then you'll find an option called "Nonlinear Subdivision Level". This will basically recursively split the curve into more straight segments for rendering. With a sufficiently high enough value it renders as a reasonably smooth curve. Still a far cry from actual curved rendering, but it's much better than nothing 🤷

@JHenneberg
Copy link
Author

Thank you. I will give it a try.
I have to realize that the documentation of VTK is quite rudimentary or hard to find (I am not talking about the doxygen documentation).

I am willing to start to provide examples for each CellType in this repository. If this is something wanted I would create an issue where we could discuss further details.

@JHenneberg JHenneberg changed the title creating a Cricle approximated by a BezierCurve creating a Circle approximated by a BezierCurve Nov 10, 2021
@JHenneberg
Copy link
Author

Thank you for the question! As far as I can tell Curve cells are relatively new in VTK and so there aren't many examples in the wild. Though after digging through their documentation and examples, I discovered that you need a "RationalWeights" attribute for bezier curves. So something like the following should create a valid VTK file:

Vtk {
    version: Version { major: 4, minor: 2 },
    title: String::new(),
    byte_order: ByteOrder::BigEndian,
    file_path: None,
    data: DataSet::inline(UnstructuredGridPiece {
        points: IOBuffer::F64(vec![
            // coordinates of node 0
            0.0, 1.0, 0.0, // coordinates of node 1
            1.0, 0.0, 0.0, // coordinates of node 2
            1.0, 1.0, 0.0,
        ]),
        cells: Cells {
            cell_verts: VertexNumbers::Legacy {
                // Number of Bezier curves.
                num_cells: 1,
                // Vertices for each curve.
                vertices: vec![3, 0, 1, 2],
            },
            types: vec![CellType::BezierCurve],
        },
        data: Attributes {
            point: vec![Attribute::DataArray(DataArray {
                name: "RationalWeights".to_string(),
                elem: ElementType::Scalars {
                    num_comp: 1,
                    lookup_table: None,
                },
                data: vec![1.0f64, 1.0, 2.0f64.sqrt() / 2.0].into(),
            })],
            ..Default::default()
        },
    }),
}

For some references, there is a writeup about bezier curves used in VTK here and some example C++ code here which can be compiled and run to produce some .vtu examples. Here is one of a quadratic bezier generated by that code:

<?xml version="1.0"?>
<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor">
  <UnstructuredGrid>
    <Piece NumberOfPoints="3" NumberOfCells="1">
      <PointData RationalWeights="RationalWeights">
        <DataArray type="Float64" Name="RationalWeights" format="ascii" RangeMin="0.7071067811865476" RangeMax="1">
          1 1 0.7071067811865476
        </DataArray>
      </PointData>
      <CellData>
      </CellData>
      <Points>
        <DataArray type="Float32" Name="Points" NumberOfComponents="3" format="ascii" RangeMin="1" RangeMax="1.4142135623730951">
          0 1 0 1 0 0
          1 1 0
          <InformationKey name="L2_NORM_RANGE" location="vtkDataArray" length="2">
            <Value index="0">
              1
            </Value>
            <Value index="1">
              1.4142135624
            </Value>
          </InformationKey>
        </DataArray>
      </Points>
      <Cells>
        <DataArray type="Int64" Name="connectivity" format="ascii" RangeMin="0" RangeMax="2">
          0 1 2
        </DataArray>
        <DataArray type="Int64" Name="offsets" format="ascii" RangeMin="3" RangeMax="3">
          3
        </DataArray>
        <DataArray type="UInt8" Name="types" format="ascii" RangeMin="75" RangeMax="75">
          75
        </DataArray>
      </Cells>
    </Piece>
  </UnstructuredGrid>
</VTKFile>

It seems that these don't appear smooth in paraview though unfortunately. That may be a good question for the Kitware folks :)

Hope this helps and good luck!

The CellType::Bezier* or CellType::Lagrange* are not documented on the official kitware documentation only on in the javascript version

It seems that these don't appear smooth in paraview though unfortunately. That may be a good question for the Kitware folks :)

Yeah this is not so obvious, but there's a way to make them "arbitrarily" smooth. You need to toggle on "Advanced Properties" for the object. Then you'll find an option called "Nonlinear Subdivision Level". This will basically recursively split the curve into more straight segments for rendering. With a sufficiently high enough value it renders as a reasonably smooth curve. Still a far cry from actual curved rendering, but it's much better than nothing 🤷

I read this aswell in the report but how can I add this "Advanced Propertie" is not described. Analysing the rust struct there is no data type AdvancedProperties or other clue. Or is it smth like this:

data: Attributes {
    point: vec![Attribute::DataArray(DataArray {
        name: "NonlinearSubdivsionLevel".to_string(),
        elem: ElementType::Scalars {
            num_comp: 1,
            lookup_table: None,
        },
        data: vec![10.0f64].into(),
    })],
    ..Default::default()
},

@Andlon
Copy link
Collaborator

Andlon commented Nov 10, 2021

I read this aswell in the report but how can I add this "Advanced Propertie" is not described. Analysing the rust struct there is no data type AdvancedProperties or other clue.

Sorry, I was not clear. This is something you need to toggle in ParaView in order for it to subdivide your curve and render it with higher resolution than the default (which draws it as a linear segment). See attached picture below!

paraview_advanced_properties

EDIT: The curve on the right here is the .vtu file that Egor provided above.

@JHenneberg
Copy link
Author

I read this aswell in the report but how can I add this "Advanced Propertie" is not described. Analysing the rust struct there is no data type AdvancedProperties or other clue.

Sorry, I was not clear. This is something you need to toggle in ParaView in order for it to subdivide your curve and render it with higher resolution than the default (which draws it as a linear segment). See attached picture below!

paraview_advanced_properties

EDIT: The curve on the right here is the .vtu file that Egor provided above.

Ok. It works. So this is just a rendering option and can not be embeeded in the *.vtu

@elrnv
Copy link
Owner

elrnv commented Nov 10, 2021

Yeah this is not so obvious, but there's a way to make them "arbitrarily" smooth. You need to toggle on "Advanced Properties" for the object. Then you'll find an option called "Nonlinear Subdivision Level". This will basically recursively split the curve into more straight segments for rendering. With a sufficiently high enough value it renders as a reasonably smooth curve. Still a far cry from actual curved rendering, but it's much better than nothing shrug

Thank you for that! I should read the docs I reference :P

Ok. It works. So this is just a rendering option and can not be embeeded in the *.vtu

Yes exactly.

I am willing to start to provide examples for each CellType in this repository. If this is something wanted I would create an issue where we could discuss further details.

I would love that, thank you! I agree that docs on this seem to be somewhat sparse, and it is not always clear from the C++ code how these files should be structured since the API is not as close to the file format as the Rust structs IMO. So I think this would be of great help!

Closing this since this particular question seems to be resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants