Using the vector_uchar type

Hi all,

Simple question, I’ve looked through many resources and haven’t found much regarding the
vector_uchar type, especially as it pertains to this, when deleting vertex data:

set_subdata(int a, int b, vector_uchar const &data)

In python, the last argument would just be an empty byte-string, but in C++ it’s specified as a vector of unsigned chars. Trying to use vector functions like push_back yields errors too:

 error C2663: 'std::vector<unsigned char,pallocator_array<unsigned char>>::push_back': 2 overloads have no legal conversion for 'this' pointer

So how would one use the vector_uchar type, to achieve the same effect an empty byte-string does in Python, i.e. delete vertex data for instance? What would I pass in as the third argument in C++?

Thanks in advance.

Here is an example for set_data(), it will work for you too. Since it is a char type.

Thanks for pointing that out, but the issue is, set_data modifies the entire raw data array, whereas set_subdata modifies only a part of the raw data array, which is what I need. When I tried passing in a char type, unsigned char type, or string type to set_subdata like this:

string empty_string="";
char blank_char='\0';
unsigned char blank_uchar='\0';

vertex_array_data_handle_p->set_subdata(remIndi*length_primitive_byte, length_primitive_byte, empty_string);

vertex_array_data_handle_p->set_subdata(remIndi*length_primitive_byte, length_primitive_byte, blank_char);

vertex_array_data_handle_p->set_subdata(remIndi*length_primitive_byte, length_primitive_byte, blank_uchar);

This results in a type-conversion error all the time:

error C2664: 'void GeomVertexArrayDataHandle::set_subdata(std::size_t,std::size_t,const vector_uchar &)': cannot convert argument 3 from 'std::string' to 'const vector_uchar &'

error C2664: 'void GeomVertexArrayDataHandle::set_subdata(std::size_t,std::size_t,const vector_uchar &)': cannot convert argument 3 from 'char' to 'const vector_uchar &' 

error C2664: 'void GeomVertexArrayDataHandle::set_subdata(std::size_t,std::size_t,const vector_uchar &)': cannot convert argument 3 from 'unsigned char' to 'const vector_uchar &'

It’s adamant about argument 3 being const vector_uchar & type and not anything else, but I can’t find any documentation on how to add elements to it, or how to initialize it as an empty string. Thoughts?

You misunderstood me.
https://docs.panda3d.org/1.10/cpp/reference/panda3d.core.GeomVertexArrayDataHandle#_CPPv4N25GeomVertexArrayDataHandle8set_dataERK12vector_uchar
https://docs.panda3d.org/1.10/cpp/reference/panda3d.core.GeomVertexArrayDataHandle#_CPPv4N25GeomVertexArrayDataHandle11set_subdataENSt6size_tENSt6size_tERK12vector_uchar

They have the same type. In the case of set_data() there is no range, in set_subdata() you specify the range of data to replace. But they have the same data type.

Yes, I need to use set_subdata() precisely because it replaces a range of data, not the entire data. I need to only replace part of the data, not all of it, which is why I can only use set_subdata().

As for the type, like I said, passing in string, char or unsigned char just gives me the type-conversion error I highlighted. The data type they reference is const vector_uchar &, but how is it used? This works, but how would I give an empty value to v_string?:

const vector_uchar v_string;

vertex_array_data_handle_p->set_subdata(remIndi*length_primitive_byte, length_primitive_byte, v_string);

It’s really a typedef to a regular vector type of unsigned char. Use it like any vector.

The empty vector is vector_uchar(). In your example it’s already initialized as empty. (The const keyword isn’t necessary.)

push_back(c) appends a single byte to the vector.

To convert a C byte array to vector_uchar, use vector_uchar(ptr, ptr + size).

To append a C byte array, use v.insert(v.end(), ptr, ptr + size).

See: std::vector - cppreference.com

1 Like

That seems to have been my newbie mistake, since this works:

unsigned char data_pointer = '\0';
vector_uchar bb;
bb.push_back(data_pointer);

But this doesn’t:

unsigned char data_pointer = '\0';
const vector_uchar bb;
bb.push_back(data_pointer);

Thanks so much for pointing that out!

Yes, you cannot mutate a const vector. Another way to initialize a vector_uchar with a single null byte, as you are doing, is as follows:

vector_uchar bb(1, 0);

The first parameter being the size of the buffer, the second one being the value to fill it with.

1 Like