materialCollection.cxx 10 KB

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