34 PStatCollector GeomTransformer::_apply_vertex_collector(
"*:Flatten:apply:vertex");
    35 PStatCollector GeomTransformer::_apply_texcoord_collector(
"*:Flatten:apply:texcoord");
    36 PStatCollector GeomTransformer::_apply_set_color_collector(
"*:Flatten:apply:set color");
    37 PStatCollector GeomTransformer::_apply_scale_color_collector(
"*:Flatten:apply:scale color");
    38 PStatCollector GeomTransformer::_apply_texture_color_collector(
"*:Flatten:apply:texture color");
    39 PStatCollector GeomTransformer::_apply_set_format_collector(
"*:Flatten:apply:set format");
    41 TypeHandle GeomTransformer::NewCollectedData::_type_handle;
    49   _max_collect_vertices(max_collect_vertices)
    58   _max_collect_vertices(copy._max_collect_vertices)
    76   VertexDataAssoc &assoc = _vdata_assoc[geom->get_vertex_data()];
    77   assoc._geoms.push_back(geom);
    78   if (might_have_unused) {
    79     assoc._might_have_unused = 
true;
    89   Thread *current_thread = Thread::get_current_thread();
    90   OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler, current_thread) {
    92     GeomNode::GeomList::iterator gi;
    94     for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
    96       PT(
Geom) geom = entry._geom.get_write_pointer();
   100   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler);
   111   nassertr(geom != 
nullptr, 
false);
   114   sv._vertex_data = geom->get_vertex_data();
   116   NewVertexData &new_data = _vertices[sv];
   117   if (new_data._vdata.is_null()) {
   120     new_vdata->transform_vertices(mat);
   121     new_data._vdata = new_vdata;
   125   if (sv._vertex_data->get_ref_count() > 1) {
   126     _vdata_assoc[new_data._vdata]._might_have_unused = 
true;
   127     _vdata_assoc[sv._vertex_data]._might_have_unused = 
true;
   143   bool any_changed = 
false;
   145   Thread *current_thread = Thread::get_current_thread();
   146   OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler, current_thread) {
   148     GeomNode::GeomList::iterator gi;
   150     for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
   152       PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   154         entry._geom = std::move(new_geom);
   159   CLOSE_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler);
   162     node->mark_internal_bounds_stale();
   178   nassertr(geom != 
nullptr, 
false);
   182   st._from = from_name;
   184   st._vertex_data = geom->get_vertex_data();
   186   NewVertexData &new_data = _texcoords[st];
   187   if (new_data._vdata.is_null()) {
   188     if (!st._vertex_data->has_column(from_name)) {
   196     if (st._vertex_data->has_column(to_name)) {
   200         st._vertex_data->get_format()->get_column(from_name);
   201       new_vdata = st._vertex_data->replace_column
   213       const LPoint4 &coord = fdata.
get_data4();
   216     new_data._vdata = new_vdata;
   220   if (st._vertex_data->get_ref_count() > 1) {
   221     _vdata_assoc[new_data._vdata]._might_have_unused = 
true;
   222     _vdata_assoc[st._vertex_data]._might_have_unused = 
true;
   239   bool any_changed = 
false;
   242   GeomNode::GeomList::iterator gi;
   244   for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
   246     PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   248       entry._geom = new_geom;
   267   sc._vertex_data = geom->get_vertex_data();
   269   NewVertexData &new_data = _fcolors[sc];
   270   if (new_data._vdata.is_null()) {
   272     if (sc._vertex_data->has_column(InternalName::get_color())) {
   273       new_data._vdata = sc._vertex_data->set_color(color);
   275       new_data._vdata = sc._vertex_data->set_color
   276         (color, 1, Geom::NT_packed_dabc, Geom::C_color);
   281   if (sc._vertex_data->get_ref_count() > 1) {
   282     _vdata_assoc[new_data._vdata]._might_have_unused = 
true;
   283     _vdata_assoc[sc._vertex_data]._might_have_unused = 
true;
   297   bool any_changed = 
false;
   300   GeomNode::GeomList::iterator gi;
   302   for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
   304     PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   306       entry._geom = new_geom;
   320   PStatTimer timer(_apply_scale_color_collector);
   322   nassertr(geom != 
nullptr, 
false);
   326   sc._vertex_data = geom->get_vertex_data();
   328   NewVertexData &new_data = _tcolors[sc];
   329   if (new_data._vdata.is_null()) {
   331     if (sc._vertex_data->has_column(InternalName::get_color())) {
   332       new_data._vdata = sc._vertex_data->scale_color(scale);
   334       new_data._vdata = sc._vertex_data->set_color
   335         (scale, 1, Geom::NT_packed_dabc, Geom::C_color);
   340   if (sc._vertex_data->get_ref_count() > 1) {
   341     _vdata_assoc[new_data._vdata]._might_have_unused = 
true;
   342     _vdata_assoc[sc._vertex_data]._might_have_unused = 
true;
   358   bool any_changed = 
false;
   361   GeomNode::GeomList::iterator gi;
   363   for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
   365     PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   367       entry._geom = new_geom;
   384                      bool keep_vertex_color) {
   385   PStatTimer timer(_apply_texture_color_collector);
   387   nassertr(geom != 
nullptr, 
false);
   390   if (peeker == 
nullptr) {
   394   if (peeker->get_x_size() == 1 &&
   395       peeker->get_y_size() == 1 &&
   396       peeker->get_z_size() == 1) {
   400     peeker->lookup(color, 0.0f, 0.0f);
   401     color.set(color[0] * base_color[0],
   402               color[1] * base_color[1],
   403               color[2] * base_color[2],
   404               color[3] * base_color[3]);
   405     if (keep_vertex_color) {
   412   bool got_mat = 
false;
   413   LMatrix4 mat = LMatrix4::ident_mat();
   414   if (tma != 
nullptr && tma->has_stage(ts)) {
   415     mat = tma->get_mat(ts);
   416     got_mat = !mat.almost_equal(LMatrix4::ident_mat());
   454   SourceTextureColors stc;
   458   stc._base_color = base_color;
   459   stc._keep_vertex_color = keep_vertex_color;
   460   stc._vertex_data = geom->get_vertex_data();
   462   NewVertexData &new_data = _tex_colors[stc];
   463   if (new_data._vdata.is_null()) {
   469     if (stc._vertex_data->has_column(InternalName::get_color())) {
   474                                  (LColor(1.0f, 1.0f, 1.0f, 1.0f), 1, Geom::NT_packed_dabc, Geom::C_color));
   475       keep_vertex_color = 
false;
   481     if (column == 
nullptr) {
   490     if (keep_vertex_color) {
   495       if (got_mat || tex3d) {
   496         while (!gtexcoord.is_at_end()) {
   497           LTexCoord3 p = gtexcoord.get_data3();
   498           LColor c = gcolor.get_data4();
   501           peeker->lookup(color, p[0], p[1], p[2]);
   502           color.set(color[0] * base_color[0] * c[0],
   503                     color[1] * base_color[1] * c[1],
   504                     color[2] * base_color[2] * c[2],
   505                     color[3] * base_color[3] * c[3]);
   506           gcolor.set_data4(color);
   509         while (!gtexcoord.is_at_end()) {
   510           LTexCoord p = gtexcoord.get_data2();
   511           LColor c = gcolor.get_data4();
   513           peeker->lookup(color, p[0], p[1]);
   514           color.set(color[0] * base_color[0] * c[0],
   515                     color[1] * base_color[1] * c[1],
   516                     color[2] * base_color[2] * c[2],
   517                     color[3] * base_color[3] * c[3]);
   518           gcolor.set_data4(color);
   526       if (got_mat || tex3d) {
   527         while (!gtexcoord.is_at_end()) {
   528           LTexCoord3 p = gtexcoord.get_data3();
   531           peeker->lookup(color, p[0], p[1], p[2]);
   532           color.set(color[0] * base_color[0],
   533                     color[1] * base_color[1],
   534                     color[2] * base_color[2],
   535                     color[3] * base_color[3]);
   536           gcolor.set_data4(color);
   539         while (!gtexcoord.is_at_end()) {
   540           LTexCoord p = gtexcoord.get_data2();
   542           peeker->lookup(color, p[0], p[1]);
   543           color.set(color[0] * base_color[0],
   544                     color[1] * base_color[1],
   545                     color[2] * base_color[2],
   546                     color[3] * base_color[3]);
   547           gcolor.set_data4(color);
   552     new_data._vdata = vdata;
   556   if (stc._vertex_data->get_ref_count() > 1) {
   557     _vdata_assoc[new_data._vdata]._might_have_unused = 
true;
   558     _vdata_assoc[stc._vertex_data]._might_have_unused = 
true;
   578   bool any_changed = 
false;
   581   GeomNode::GeomList::iterator gi;
   583   for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
   585     CPT(
RenderState) geom_state = state->compose(entry._state);
   590       if (ta2->get_num_on_stages() > 0) {
   592         Texture *tex = ta2->get_on_texture(ts);
   596         LColor base_color(1.0f, 1.0f, 1.0f, 1.0f);
   597         bool keep_vertex_color = 
true;
   598         if (ca != 
nullptr && ca->get_color_type() == ColorAttrib::T_flat) {
   599           base_color = ca->get_color();
   600           keep_vertex_color = 
false;
   603         PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   605           entry._geom = new_geom;
   608           if (new_geom->get_vertex_data()->has_column(InternalName::get_color())) {
   610             CPT(
RenderState) color_state = entry._state->set_attrib(ColorAttrib::make_vertex());
   611             if (entry._state != color_state) {
   612               entry._state = color_state;
   619         CPT(
RenderState) no_tex_state = entry._state->remove_attrib(TextureAttrib::get_class_slot());
   620         if (entry._state != no_tex_state) {
   621           entry._state = no_tex_state;
   637   bool any_changed = 
false;
   640   GeomNode::GeomList::iterator gi;
   642   for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
   644     CPT(
RenderState) new_state = state->compose(entry._state);
   645     if (entry._state != new_state) {
   646       entry._state = new_state;
   660   PStatTimer timer(_apply_set_format_collector);
   662   nassertr(geom != 
nullptr, 
false);
   665   sf._format = new_format;
   666   sf._vertex_data = geom->get_vertex_data();
   668   NewVertexData &new_data = _format[sf];
   669   if (new_data._vdata.is_null()) {
   670     if (sf._vertex_data->get_format() == new_format) {
   677     new_vdata->set_format(new_format);
   678     new_data._vdata = new_vdata;
   682   if (sf._vertex_data->get_ref_count() > 1) {
   683     _vdata_assoc[new_data._vdata]._might_have_unused = 
true;
   684     _vdata_assoc[sf._vertex_data]._might_have_unused = 
true;
   697   if (!format->has_column(column)) {
   702   new_format->remove_column(column);
   703   new_format->pack_columns();
   704   format = GeomVertexFormat::register_format(new_format);
   716   bool any_changed = 
false;
   719   GeomNode::GeomList::iterator gi;
   721   for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
   723     PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   725       entry._geom = new_geom;
   752   StateTable state_table;
   754   for (
int i = 0; i < (int)geoms->size(); i++) {
   756     CPT(
RenderState) canon = entry._state->remove_attrib(ColorAttrib::get_class_slot());
   757     state_table[canon].push_back(i);
   762   bool any_changed = 
false;
   763   StateTable::iterator si;
   764   for (si = state_table.begin(); si != state_table.end(); si++) {
   770     bool mismatch = 
false;
   771     for (
int i = 1; i < (int)indices.size(); i++) {
   772       if ((*geoms)[indices[i]]._state != (*geoms)[indices[0]]._state) {
   786     for (
int i = 0; i < (int)indices.size(); i++) {
   788       const RenderAttrib *ra = entry._state->get_attrib_def(ColorAttrib::get_class_slot());
   792         if (!entry._geom.get_read_pointer()->get_vertex_data()->has_column(InternalName::get_color())) {
   793           PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   794           if (
set_color(new_geom, LColor(1,1,1,1))) {
   795             entry._geom = new_geom;
   802         PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
   804           entry._geom = new_geom;
   807       entry._state = canon_state->add_attrib(ColorAttrib::make_vertex());
   821   nassertr(geom != 
nullptr, 
false);
   823   NewVertexData &new_data = _reversed_normals[orig_data];
   824   if (new_data._vdata.is_null()) {
   825     new_data._vdata = orig_data->reverse_normals();
   828   if (new_data._vdata == orig_data) {
   834   if (orig_data->get_ref_count() > 1) {
   835     _vdata_assoc[new_data._vdata]._might_have_unused = 
true;
   836     _vdata_assoc[orig_data]._might_have_unused = 
true;
   859   for (
int i = 0; i < num_geoms; ++i) {
   860     CPT(
Geom) orig_geom = node->get_geom(i);
   861     bool has_normals = (orig_geom->get_vertex_data()->has_column(InternalName::get_normal()));
   865       PT(
Geom) new_geom = orig_geom->reverse();
   873       node->modify_geom(i)->doubleside_in_place();
   877   return (num_geoms != 0);
   896   for (
int i = 0; i < num_geoms; ++i) {
   897     PT(
Geom) geom = node->modify_geom(i);
   898     geom->reverse_in_place();
   902   return (num_geoms != 0);
   914   VertexDataAssocMap::iterator vi;
   915   for (vi = _vdata_assoc.begin(); vi != _vdata_assoc.end(); ++vi) {
   917     VertexDataAssoc &assoc = (*vi).second;
   918     if (assoc._might_have_unused) {
   919       assoc.remove_unused_vertices(vdata);
   922   _vdata_assoc.clear();
   928   _reversed_normals.clear();
   946   if (vdata->get_num_rows() > _max_collect_vertices) {
   954   if ((collect_bits & SceneGraphReducer::CVD_name) != 0) {
   955     key._name = vdata->get_name();
   957   if ((collect_bits & SceneGraphReducer::CVD_format) != 0) {
   958     key._format = format;
   960   if ((collect_bits & SceneGraphReducer::CVD_usage_hint) != 0) {
   961     key._usage_hint = vdata->get_usage_hint();
   963     key._usage_hint = Geom::UH_unspecified;
   965   if ((collect_bits & SceneGraphReducer::CVD_animation_type) != 0) {
   966     key._animation_type = format->get_animation().get_animation_type();
   968     key._animation_type = Geom::AT_none;
   971   AlreadyCollectedMap::const_iterator ai;
   972   ai = _already_collected_map.find(vdata);
   973   if (ai != _already_collected_map.end()) {
   975     const AlreadyCollectedData &acd = (*ai).second;
   976     SourceGeom source_geom;
   977     source_geom._geom = geom;
   978     source_geom._vertex_offset = acd._vertex_offset;
   979     acd._ncd->_source_geoms.push_back(source_geom);
   984   NewCollectedMap::iterator ni = _new_collected_map.find(key);
   985   NewCollectedData *ncd;
   986   if (ni != _new_collected_map.end()) {
   992     ncd = 
new NewCollectedData(vdata);
   993     _new_collected_list.push_back(ncd);
   994     _new_collected_map[key] = ncd;
   997   if (ncd->_new_format != format) {
   998     ncd->_new_format = format->get_union_format(ncd->_new_format);
  1001   int this_num_vertices = vdata->get_num_rows();
  1004       ncd->_num_vertices + this_num_vertices > _max_collect_vertices) {
  1007     ncd = 
new NewCollectedData(vdata);
  1008     _new_collected_list.push_back(ncd);
  1009     _new_collected_map[key] = ncd;
  1012   int vertex_offset = ncd->_num_vertices;
  1014   AlreadyCollectedData &acd = _already_collected_map[vdata];
  1016   acd._vertex_offset = vertex_offset;
  1018   SourceGeom source_geom;
  1019   source_geom._geom = geom;
  1020   source_geom._vertex_offset = vertex_offset;
  1021   ncd->_source_geoms.push_back(source_geom);
  1023   SourceData source_data;
  1024   source_data._vdata = vdata;
  1025   source_data._num_vertices = this_num_vertices;
  1027   ncd->_source_datas.push_back(source_data);
  1028   ncd->_num_vertices += this_num_vertices;
  1048   int num_adjusted = 0;
  1052   GeomNode::GeomList::iterator gi;
  1054   for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
  1056     PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
  1057     entry._geom = new_geom;
  1059     if ((collect_bits & SceneGraphReducer::CVD_avoid_dynamic) != 0 &&
  1060         new_geom->get_vertex_data()->get_usage_hint() < Geom::UH_static) {
  1063       if (dynamic == 
nullptr) {
  1073   if (dynamic != 
nullptr) {
  1078   return num_adjusted;
  1092   int num_adjusted = 0;
  1094   NewCollectedList::iterator nci;
  1095   for (nci = _new_collected_list.begin();
  1096        nci != _new_collected_list.end();
  1098     NewCollectedData *ncd = (*nci);
  1100       num_adjusted += ncd->apply_format_only_changes();
  1102       num_adjusted += ncd->apply_collect_changes();
  1107   _new_collected_list.clear();
  1108   _new_collected_map.clear();
  1109   _already_collected_map.clear();
  1111   return num_adjusted;
  1128   vdata = munger->premunge_data(vdata);
  1129   CPT(
Geom) pgeom = geom;
  1130   munger->premunge_geom(pgeom, vdata);
  1132   PT(
Geom) geom_copy = pgeom->make_copy();
  1133   geom_copy->set_vertex_data(vdata);
  1141 GeomTransformer::NewCollectedData::
  1144   _vdata_name = source_data->
get_name();
  1154 int GeomTransformer::NewCollectedData::
  1155 apply_format_only_changes() {
  1156   int num_modified = 0;
  1164   SourceGeoms::iterator sgi;
  1165   for (sgi = _source_geoms.begin(); sgi != _source_geoms.end(); ++sgi) {
  1166     SourceGeom &sg = (*sgi);
  1169     if (orig_data->get_format() != _new_format) {
  1170       VDataMap::iterator mi = vdata_map.find(orig_data);
  1171       if (mi != vdata_map.end()) {
  1173         sg._geom->set_vertex_data((*mi).second);
  1177         CPT(
GeomVertexData) new_data = orig_data->convert_to(_new_format);
  1178         vdata_map[orig_data] = new_data;
  1181         sg._geom->set_vertex_data(new_data);
  1186   return num_modified;
  1193 int GeomTransformer::NewCollectedData::
  1194 apply_collect_changes() {
  1195   if (_num_vertices == 0) {
  1202   _new_data->unclean_set_num_rows(_num_vertices);
  1205   int vertex_offset = 0;
  1206   SourceDatas::iterator sdi;
  1207   for (sdi = _source_datas.begin(); sdi != _source_datas.end(); ++sdi) {
  1208     SourceData &sd = (*sdi);
  1211     if (_new_format != vdata->get_format()) {
  1215       vdata = vdata->convert_to(_new_format);
  1218     append_vdata(vdata, vertex_offset);
  1219     vertex_offset += sd._num_vertices;
  1222   nassertr(vertex_offset == _num_vertices, 0);
  1224   if (_new_btable != 
nullptr) {
  1225     _new_btable->set_rows(_new_btable_rows);
  1226     _new_data->set_transform_blend_table(_new_btable);
  1232   _new_btable.clear();
  1233   _new_btable_rows.clear();
  1242 void GeomTransformer::NewCollectedData::
  1247     size_t stride = (size_t)_new_format->get_array(i)->get_stride();
  1248     size_t start_byte = (size_t)vertex_offset * stride;
  1249     size_t copy_bytes = old_handle->get_data_size_bytes();
  1250     nassertv(start_byte + copy_bytes <= new_handle->get_data_size_bytes());
  1252     new_handle->copy_subdata_from(start_byte, copy_bytes, old_handle, 0, copy_bytes);
  1261       _new_data->get_transform_table() != 
nullptr) {
  1270       temp_table->add_transform(identity_transform);
  1271       old_table = TransformTable::register_table(temp_table);
  1278     AddedTransforms added_transforms;
  1280     int num_old_transforms = old_table->get_num_transforms();
  1281     for (
int i = 0; i < num_old_transforms; i++) {
  1282       added_transforms[old_table->get_transform(i)] = i;
  1289     if (_new_data->get_transform_table() != 
nullptr) {
  1290       new_table = 
new TransformTable(*_new_data->get_transform_table());
  1298     IndexMap transform_map;
  1301     transform_map.reserve(num_transforms);
  1302     for (
int ti = 0; ti < num_transforms; ++ti) {
  1304       AddedTransforms::iterator ai = added_transforms.find(transform);
  1305       if (ai != added_transforms.end()) {
  1307         transform_map.push_back((*ai).second);
  1310         int tj = new_table->add_transform(transform);
  1311         transform_map.push_back(tj);
  1312         added_transforms[transform] = tj;
  1315     _new_data->set_transform_table(TransformTable::register_table(new_table));
  1321     if (index.has_column()) {
  1322       int num_values = index.get_column()->get_num_values();
  1325       index.set_row_unsafe(vertex_offset);
  1326       for (
int ci = 0; ci < num_rows; ++ci) {
  1327         LVecBase4i indices = index.get_data4i();
  1328         for (
int i = 0; i < num_values; i++) {
  1329           nassertv(indices[i] >= 0 && indices[i] < (
int)transform_map.size());
  1330           indices[i] = transform_map[indices[i]];
  1332         index.set_data4i(indices);
  1337   if (vdata->get_transform_blend_table() != 
nullptr) {
  1347     if (_new_btable == 
nullptr) {
  1353     new_rows <<= vertex_offset;
  1354     _new_btable_rows |= new_rows;
  1359     int num_blends = old_btable->get_num_blends();
  1360     blend_map.reserve(num_blends);
  1361     for (
int bi = 0; bi < num_blends; ++bi) {
  1362       int bj = _new_btable->add_blend(old_btable->get_blend(bi));
  1363       blend_map.push_back(bj);
  1369     if (index.has_column()) {
  1371       index.set_row_unsafe(vertex_offset);
  1373       for (
int ci = 0; ci < num_rows; ++ci) {
  1374         int orig_index = index.get_data1i();
  1375         nassertv(orig_index >= 0 && orig_index < (
int)blend_map.size());
  1376         int new_index = blend_map[orig_index];
  1377         index.set_data1i(new_index);
  1390     if (_new_data->get_slider_table() != 
nullptr) {
  1391       new_sliders = 
new SliderTable(*_new_data->get_slider_table());
  1396     for (
int si = 0; si < num_sliders; ++si) {
  1398       new_rows <<= vertex_offset;
  1399       new_sliders->add_slider(old_sliders->
get_slider(si), new_rows);
  1401     _new_data->set_slider_table(SliderTable::register_table(new_sliders));
  1408 void GeomTransformer::NewCollectedData::
  1410   SourceGeoms::iterator sgi;
  1411   for (sgi = _source_geoms.begin(); sgi != _source_geoms.end(); ++sgi) {
  1412     SourceGeom &sg = (*sgi);
  1413     sg._geom->offset_vertices(_new_data, sg._vertex_offset);
  1420 void GeomTransformer::VertexDataAssoc::
  1422   if (_geoms.empty()) {
  1430   bool any_referenced = 
false;
  1431   GeomList::iterator gi;
  1432   for (gi = _geoms.begin(); gi != _geoms.end(); ++gi) {
  1434     if (geom->get_vertex_data() != vdata) {
  1438     any_referenced = 
true;
  1439     int num_primitives = geom->get_num_primitives();
  1440     for (
int i = 0; i < num_primitives; ++i) {
  1442       reader.get_referenced_vertices(referenced_vertices);
  1446   if (!any_referenced) {
  1452   if (num_vertices <= new_num_vertices) {
  1454     nassertv(num_vertices == new_num_vertices);
  1459   int *remap_array = (
int *)alloca(
sizeof(
int) * num_vertices);
  1463   for (index = 0; index < num_vertices; ++index) {
  1464     if (referenced_vertices.
get_bit(index)) {
  1465       while (next_index <= index) {
  1466         remap_array[next_index] = new_index;
  1472   while (next_index < num_vertices) {
  1473     remap_array[next_index] = new_num_vertices - 1;
  1479   new_vdata->unclean_set_num_rows(new_num_vertices);
  1482   nassertv(num_arrays == new_vdata->get_num_arrays());
  1485   reader.check_array_readers();
  1487   writer.check_array_writers();
  1489   for (
size_t a = 0; a < num_arrays; ++a) {
  1493     int stride = array_reader->get_array_format()->get_stride();
  1494     nassertv(stride == array_writer->get_array_format()->get_stride());
  1498     for (index = 0; index < num_vertices; ++index) {
  1499       if (referenced_vertices.
get_bit(index)) {
  1502                                         index * stride, stride);
  1510   if (!tbtable.is_null()) {
  1514     for (
int si = 0; si < num_subranges; ++si) {
  1517       nassertv(from >= 0 && from < num_vertices && to > from && to <= num_vertices);
  1518       int new_from = remap_array[from];
  1519       int new_to = remap_array[to - 1] + 1;
  1520       nassertv(new_from >= 0 && new_from < new_num_vertices && new_to >= new_from && new_to <= new_num_vertices);
  1521       new_rows.
set_range(new_from, new_to - new_from);
  1523     tbtable->set_rows(new_rows);
  1527   for (gi = _geoms.begin(); gi != _geoms.end(); ++gi) {
  1529     if (geom->get_vertex_data() != vdata) {
  1533     int num_primitives = geom->get_num_primitives();
  1534     for (
int i = 0; i < num_primitives; ++i) {
  1536       prim->make_indexed();
  1540       while (!rewriter.is_at_end()) {
  1541         index = rewriter.get_data1i();
  1542         nassertv(index >= 0 && index < num_vertices);
  1543         new_index = remap_array[index];
  1544         nassertv(new_index >= 0 && new_index < new_num_vertices);
  1545         rewriter.set_data1i(new_index);
 
get_geom_state
Returns the RenderState associated with the nth geom of the node.
This class records a set of integers, where each integer is either present or not present in the set.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL map.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
const SparseArray & get_slider_rows(size_t n) const
Returns the set of rows (vertices) governed by the nth slider in the table.
const LVecBase4 & get_data4()
Returns the data associated with the read row, expressed as a 4-component value, and advances the rea...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This defines how a single column is interleaved within a vertex array stored within a Geom.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A dynamic array with an unlimited number of bits.
get_format
Returns a pointer to the GeomVertexFormat structure that defines this data.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight class that represents a single element that may be timed and/or counted via stats.
Stores the total set of VertexSliders that the vertices in a particular GeomVertexData object might d...
get_current_thread
Returns a pointer to the currently-executing Thread object.
get_num_sliders
Returns the number of sliders in the table.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_on_bits() const
Returns the number of bits that are set to 1 in the array.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
void set_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row.
size_t get_num_subranges() const
Returns the number of separate subranges stored in the SparseArray.
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
int get_num_rows() const
Returns the number of rows stored within all the arrays.
Encodes a string name in a hash table, mapping it to a pointer.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
An instance of this object is returned by Texture::peek().
Applies a transform matrix to UV's before they are rendered.
void set_range(int low_bit, int size)
Sets the indicated range of bits on.
int get_subrange_begin(size_t n) const
Returns the first numeric element in the nth subrange.
void set_vertex_data(const GeomVertexData *data)
Replaces the Geom's underlying vertex data table with a completely new table.
get_num_geoms
Returns the number of geoms in the node.
A thread; that is, a lightweight process.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void copy_subdata_from(size_t to_start, size_t to_size, const GeomVertexArrayDataHandle *other, size_t from_start, size_t from_size)
Copies a portion of the data array from the other object into a portion of the data array of this obj...
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise.
This is similar to RefCountObj, but it implements a CopyOnWriteObject inheritance instead of a Refere...
get_slider_table
Returns a const pointer to the SliderTable assigned to this data.
get_num_arrays
Returns the number of individual arrays stored within the data.
get_usage_hint
Returns the usage hint that was passed to the constructor, and which will be passed to each array dat...
Indicates what color should be applied to renderable geometry.
int get_subrange_end(size_t n) const
Returns the last numeric element, plus one, in the nth subrange.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
get_name
Returns the name passed to the constructor, if any.
TypeHandle is the identifier used to differentiate C++ class types.
get_slider
Returns the nth slider in the table.
int get_num_components() const
Returns the number of components of the column: the number of instances of the NumericType in each el...
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
Defines the properties of a named stage of the multitexture pipeline.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_color_type
Returns the type of color specified by this ColorAttrib.
get_texcoord_name
See set_texcoord_name.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that holds Geom objects, renderable pieces of geometry.
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
get_transform_table
Returns a const pointer to the TransformTable assigned to this data.
This is the data for one array of a GeomVertexData structure.