Panda3D
materialCollection.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file materialCollection.cxx
10  * @author drose
11  * @date 2002-03-16
12  */
13 
14 #include "materialCollection.h"
15 
16 #include "indent.h"
17 
18 /**
19  *
20  */
21 MaterialCollection::
22 MaterialCollection() {
23 }
24 
25 /**
26  *
27  */
28 MaterialCollection::
29 MaterialCollection(const MaterialCollection &copy) :
30  _materials(copy._materials)
31 {
32 }
33 
34 /**
35  *
36  */
37 void MaterialCollection::
38 operator = (const MaterialCollection &copy) {
39  _materials = copy._materials;
40 }
41 
42 /**
43  * Adds a new Material to the collection.
44  */
46 add_material(Material *node_material) {
47  // If the pointer to our internal array is shared by any other
48  // MaterialCollections, we have to copy the array now so we won't
49  // inadvertently modify any of our brethren MaterialCollection objects.
50 
51  if (_materials.get_ref_count() > 1) {
52  Materials old_materials = _materials;
53  _materials = Materials::empty_array(0);
54  _materials.v() = old_materials.v();
55  }
56 
57  _materials.push_back(node_material);
58 }
59 
60 /**
61  * Removes the indicated Material from the collection. Returns true if the
62  * material was removed, false if it was not a member of the collection.
63  */
65 remove_material(Material *node_material) {
66  int material_index = -1;
67  for (int i = 0; material_index == -1 && i < (int)_materials.size(); i++) {
68  if (_materials[i] == node_material) {
69  material_index = i;
70  }
71  }
72 
73  if (material_index == -1) {
74  // The indicated material was not a member of the collection.
75  return false;
76  }
77 
78  // If the pointer to our internal array is shared by any other
79  // MaterialCollections, we have to copy the array now so we won't
80  // inadvertently modify any of our brethren MaterialCollection objects.
81 
82  if (_materials.get_ref_count() > 1) {
83  Materials old_materials = _materials;
84  _materials = Materials::empty_array(0);
85  _materials.v() = old_materials.v();
86  }
87 
88  _materials.erase(_materials.begin() + material_index);
89  return true;
90 }
91 
92 /**
93  * Adds all the Materials indicated in the other collection to this material.
94  * The other materials are simply appended to the end of the materials in this
95  * list; duplicates are not automatically removed.
96  */
99  int other_num_materials = other.get_num_materials();
100  for (int i = 0; i < other_num_materials; i++) {
101  add_material(other.get_material(i));
102  }
103 }
104 
105 
106 /**
107  * Removes from this collection all of the Materials listed in the other
108  * collection.
109  */
112  Materials new_materials;
113  int num_materials = get_num_materials();
114  for (int i = 0; i < num_materials; i++) {
115  PT(Material) material = get_material(i);
116  if (!other.has_material(material)) {
117  new_materials.push_back(material);
118  }
119  }
120  _materials = new_materials;
121 }
122 
123 /**
124  * Removes any duplicate entries of the same Materials on this collection. If
125  * a Material appears multiple times, the first appearance is retained;
126  * subsequent appearances are removed.
127  */
130  Materials new_materials;
131 
132  int num_materials = get_num_materials();
133  for (int i = 0; i < num_materials; i++) {
134  PT(Material) material = get_material(i);
135  bool duplicated = false;
136 
137  for (int j = 0; j < i && !duplicated; j++) {
138  duplicated = (material == get_material(j));
139  }
140 
141  if (!duplicated) {
142  new_materials.push_back(material);
143  }
144  }
145 
146  _materials = new_materials;
147 }
148 
149 /**
150  * Returns true if the indicated Material appears in this collection, false
151  * otherwise.
152  */
154 has_material(Material *material) const {
155  for (int i = 0; i < get_num_materials(); i++) {
156  if (material == get_material(i)) {
157  return true;
158  }
159  }
160  return false;
161 }
162 
163 /**
164  * Removes all Materials from the collection.
165  */
167 clear() {
168  _materials.clear();
169 }
170 
171 /**
172  * Returns the material in the collection with the indicated name, if any, or
173  * NULL if no material has that name.
174  */
176 find_material(const std::string &name) const {
177  int num_materials = get_num_materials();
178  for (int i = 0; i < num_materials; i++) {
179  Material *material = get_material(i);
180  if (material->get_name() == name) {
181  return material;
182  }
183  }
184  return nullptr;
185 }
186 
187 /**
188  * Returns the number of Materials in the collection.
189  */
192  return _materials.size();
193 }
194 
195 /**
196  * Returns the nth Material in the collection.
197  */
199 get_material(int index) const {
200  nassertr(index >= 0 && index < (int)_materials.size(), nullptr);
201 
202  return _materials[index];
203 }
204 
205 /**
206  * Returns the nth Material in the collection. This is the same as
207  * get_material(), but it may be a more convenient way to access it.
208  */
210 operator [] (int index) const {
211  nassertr(index >= 0 && index < (int)_materials.size(), nullptr);
212 
213  return _materials[index];
214 }
215 
216 /**
217  * Returns the number of materials in the collection. This is the same thing
218  * as get_num_materials().
219  */
221 size() const {
222  return _materials.size();
223 }
224 
225 /**
226  * Writes a brief one-line description of the MaterialCollection to the
227  * indicated output stream.
228  */
230 output(std::ostream &out) const {
231  if (get_num_materials() == 1) {
232  out << "1 Material";
233  } else {
234  out << get_num_materials() << " Materials";
235  }
236 }
237 
238 /**
239  * Writes a complete multi-line description of the MaterialCollection to the
240  * indicated output stream.
241  */
243 write(std::ostream &out, int indent_level) const {
244  for (int i = 0; i < get_num_materials(); i++) {
245  indent(out, indent_level) << *get_material(i) << "\n";
246  }
247 }
Material * operator [](int index) const
Returns the nth Material in the collection.
bool has_material(Material *material) const
Returns true if the indicated Material appears in this collection, false otherwise.
int size() const
Returns the number of materials in the collection.
void add_material(Material *node_material)
Adds a new Material to the collection.
void write(std::ostream &out, int indent_level=0) const
Writes a complete multi-line description of the MaterialCollection to the indicated output stream.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
void output(std::ostream &out) const
Writes a brief one-line description of the MaterialCollection to the indicated output stream.
Material * get_material(int index) const
Returns the nth Material in the collection.
Material * find_material(const std::string &name) const
Returns the material in the collection with the indicated name, if any, or NULL if no material has th...
void clear()
Removes all Materials from the collection.
Defines the way an object appears in the presence of lighting.
Definition: material.h:43
void remove_duplicate_materials()
Removes any duplicate entries of the same Materials on this collection.
void remove_materials_from(const MaterialCollection &other)
Removes from this collection all of the Materials listed in the other collection.
void add_materials_from(const MaterialCollection &other)
Adds all the Materials indicated in the other collection to this material.
int get_num_materials() const
Returns the number of Materials in the collection.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool remove_material(Material *node_material)
Removes the indicated Material from the collection.