3 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version. The Blender
9 * Foundation also sells licenses for use in proprietary software under
10 * the Blender License. See http://www.blender.org/BL/ for information
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23 * All rights reserved.
25 * The Original Code is: all of this file.
27 * Contributor(s): none yet.
29 * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 #ifndef NAN_INCLUDED_LOD_TaggedSetOps_h
33 #define NAN_INCLUDED_LOD_TaggedSetOps_h
35 #include "MEM_NonCopyable.h"
39 * This class contains some utility functions for finding the intersection,
40 * union, and difference of a collection of stl vector of indices into
41 * a set of primitives.
43 * These are mainly used as helper functions in the decimation and bsp
46 * This template class assumes that each value of type IndexType encountered
47 * in the list is a valid index into an array of primitives. This is not
48 * checked at run-time and is left to the user to insure. Prmitives of
49 * type ObjectType must have the following public methods to be used by
50 * this template class:
53 * OpenTag(void) --- return a persistent tag value for the primitive
56 * SetOpenTag(int bla) --- set the persistent tag value for this primitive to bla.
59 * SelectTag() --- return a persistent boolean tag for this primitive
62 * SetSelectTag(bool bla) --- set the persistent boolean tag for this primitive to bla.
64 * Here persistent means that the tag should be associated with the object for the
65 * entire lifetime of the primitive. Again none of this stuff is enforced you have
66 * to make sure that your primitives do the right thing. Often these tags can be
67 * cunningly stowed away inside some of the spare bits in the primitive. See
68 * CTR_TaggedIndex for such a class.
73 <class IndexType, class ObjectType>
74 class CTR_TaggedSetOps : public MEM_NonCopyable {
81 const std::vector< std::vector<IndexType> > &index_list,
82 std::vector<ObjectType> &primitives,
83 std::vector<IndexType> &output,
88 // iterate through vectors in index_list
89 // iterate through individual members of each vector
90 // mark each obejct that the index points to
92 typename std::vector< std::vector<IndexType> >::const_iterator
93 last_vector = index_list.end();
94 typename std::vector< std::vector<IndexType> >::const_iterator
95 start_vector = index_list.begin();
97 // FIXME some temporary space
99 std::vector<IndexType> temp_union;
100 temp_union.reserve(64);
104 for (; start_vector != last_vector; ++start_vector) {
106 typename std::vector<IndexType>::const_iterator
107 last_index = start_vector->end();
108 typename std::vector<IndexType>::const_iterator
109 start_index = start_vector->begin();
111 for (; start_index != last_index; ++start_index) {
113 ObjectType & prim = primitives[*start_index];
115 if (!prim.OpenTag()) {
117 temp_union.push_back(*start_index);
119 int tag = prim.OpenTag();
120 tag = (tag & mask) >> shift;
122 prim.SetOpenTag((prim.OpenTag() & ~mask)| ((tag << shift) & mask));
128 // now iterate through the union and pull out all those with the right tag
130 typename std::vector<IndexType>::const_iterator last_index =
132 typename std::vector<IndexType>::const_iterator start_index =
135 for (; start_index != last_index; ++start_index) {
137 ObjectType & prim = primitives[*start_index];
139 if (prim.OpenTag() == tag_num) {
140 //it's part of the intersection!
142 output.push_back(*start_index);
143 // because we're iterating through the union
144 // it's safe to remove the tag at this point
146 prim.SetOpenTag(prim.OpenTag() & ~mask);
151 // note not a strict set intersection!
152 // if x appears twice in b and is part of the intersection
153 // it will appear twice in the intersection
158 const std::vector<IndexType> &a,
159 const std::vector<IndexType> &b,
160 std::vector<ObjectType> &primitives,
161 std::vector<IndexType> &output
164 typename std::vector<IndexType>::const_iterator last_index =
166 typename std::vector<IndexType>::const_iterator start_index =
169 for (; start_index != last_index; ++start_index) {
170 ObjectType & prim = primitives[*start_index];
171 prim.SetSelectTag(true);
173 last_index = b.end();
174 start_index = b.begin();
176 for (; start_index != last_index; ++start_index) {
177 ObjectType & prim = primitives[*start_index];
178 if (prim.SelectTag()) {
179 output.push_back(*start_index);
183 last_index = a.end();
184 start_index = a.begin();
186 for (; start_index != last_index; ++start_index) {
187 ObjectType & prim = primitives[*start_index];
188 prim.SetSelectTag(false);
196 std::vector< std::vector<IndexType> > &index_list,
197 std::vector<ObjectType> &primitives,
198 std::vector<IndexType> &output
201 // iterate through vectors in index_list
202 // iterate through individual members of each vector
203 // mark each obejct that the index points to
205 typename std::vector< std::vector<IndexType> >::const_iterator
206 last_vector = index_list.end();
207 typename std::vector< std::vector<IndexType> >::iterator
208 start_vector = index_list.begin();
210 for (; start_vector != last_vector; ++start_vector) {
212 typename std::vector<IndexType>::const_iterator
213 last_index = start_vector->end();
214 typename std::vector<IndexType>::iterator
215 start_index = start_vector->begin();
217 for (; start_index != last_index; ++start_index) {
219 ObjectType & prim = primitives[*start_index];
221 if (!prim.SelectTag()) {
223 output.push_back(*start_index);
224 prim.SetSelectTag(true);
229 // now iterate through the union and reset the tags
231 typename std::vector<IndexType>::const_iterator last_index =
233 typename std::vector<IndexType>::iterator start_index =
236 for (; start_index != last_index; ++start_index) {
238 ObjectType & prim = primitives[*start_index];
239 prim.SetSelectTag(false);
247 std::vector< IndexType> &a,
248 std::vector< IndexType> &b,
249 std::vector<ObjectType> &primitives,
250 std::vector< IndexType> &output
253 // iterate through b mark all
254 // iterate through a and add to output all unmarked
256 typename std::vector<IndexType>::const_iterator last_index =
258 typename std::vector<IndexType>::iterator start_index =
261 for (; start_index != last_index; ++start_index) {
263 ObjectType & prim = primitives[*start_index];
264 prim.SetSelectTag(true);
267 last_index = a.end();
268 start_index = a.begin();
270 for (; start_index != last_index; ++start_index) {
272 ObjectType & prim = primitives[*start_index];
273 if (!prim.SelectTag()) {
274 output.push_back(*start_index);
280 last_index = b.end();
281 start_index = b.begin();
283 for (; start_index != last_index; ++start_index) {
285 ObjectType & prim = primitives[*start_index];
286 prim.SetSelectTag(false);
292 // private constructor - this class is not meant for