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  */
191 get_num_materials() const {
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.
void add_materials_from(const MaterialCollection &other)
Adds all the Materials indicated in the other collection to this material.
bool has_material(Material *material) const
Returns true if the indicated Material appears in this collection, false otherwise.
void remove_duplicate_materials()
Removes any duplicate entries of the same Materials on this collection.
Material * get_material(int index) const
Returns the nth Material in the collection.
bool remove_material(Material *node_material)
Removes the indicated Material from the collection.
void output(std::ostream &out) const
Writes a brief one-line description of the MaterialCollection to the indicated output stream.
int get_num_materials() const
Returns the number of Materials in the collection.
void remove_materials_from(const MaterialCollection &other)
Removes from this collection all of the Materials listed in the other 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.
int size() const
Returns the number of materials 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.
void add_material(Material *node_material)
Adds a new Material to the collection.
Defines the way an object appears in the presence of lighting.
Definition: material.h:43
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.