Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "mesh.h" 00020 #include "attribute.h" 00021 00022 #include "util_debug.h" 00023 #include "util_foreach.h" 00024 00025 CCL_NAMESPACE_BEGIN 00026 00027 /* Attribute */ 00028 00029 void Attribute::set(ustring name_, TypeDesc type_, Element element_) 00030 { 00031 name = name_; 00032 type = type_; 00033 element = element_; 00034 std = STD_NONE; 00035 00036 /* string and matrix not supported! */ 00037 assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor || 00038 type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || 00039 type == TypeDesc::TypeNormal); 00040 } 00041 00042 void Attribute::reserve(int numverts, int numtris) 00043 { 00044 buffer.resize(buffer_size(numverts, numtris), 0); 00045 } 00046 00047 size_t Attribute::data_sizeof() 00048 { 00049 if(type == TypeDesc::TypeFloat) 00050 return sizeof(float); 00051 else 00052 return sizeof(float3); 00053 } 00054 00055 size_t Attribute::element_size(int numverts, int numtris) 00056 { 00057 if(element == VERTEX) 00058 return numverts; 00059 else if(element == FACE) 00060 return numtris; 00061 else 00062 return numtris*3; 00063 } 00064 00065 size_t Attribute::buffer_size(int numverts, int numtris) 00066 { 00067 return element_size(numverts, numtris)*data_sizeof(); 00068 } 00069 00070 bool Attribute::same_storage(TypeDesc a, TypeDesc b) 00071 { 00072 if(a == b) 00073 return true; 00074 00075 if(a == TypeDesc::TypeColor || a == TypeDesc::TypePoint || 00076 a == TypeDesc::TypeVector || a == TypeDesc::TypeNormal) 00077 if(b == TypeDesc::TypeColor || b == TypeDesc::TypePoint || 00078 b == TypeDesc::TypeVector || b == TypeDesc::TypeNormal) 00079 return true; 00080 00081 return false; 00082 } 00083 00084 ustring Attribute::standard_name(Attribute::Standard std) 00085 { 00086 if(std == Attribute::STD_VERTEX_NORMAL) 00087 return ustring("N"); 00088 else if(std == Attribute::STD_FACE_NORMAL) 00089 return ustring("Ng"); 00090 else if(std == Attribute::STD_UV) 00091 return ustring("uv"); 00092 else if(std == Attribute::STD_GENERATED) 00093 return ustring("generated"); 00094 else if(std == Attribute::STD_POSITION_UNDEFORMED) 00095 return ustring("undeformed"); 00096 else if(std == Attribute::STD_POSITION_UNDISPLACED) 00097 return ustring("undisplaced"); 00098 00099 return ustring(); 00100 } 00101 00102 /* Attribute Set */ 00103 00104 AttributeSet::AttributeSet(Mesh *mesh_) 00105 { 00106 mesh = mesh_; 00107 } 00108 00109 AttributeSet::~AttributeSet() 00110 { 00111 } 00112 00113 Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element element) 00114 { 00115 Attribute *attr = find(name); 00116 00117 if(attr) { 00118 /* return if same already exists */ 00119 if(attr->type == type && attr->element == element) 00120 return attr; 00121 00122 /* overwrite attribute with same name but different type/element */ 00123 remove(name); 00124 } 00125 00126 attributes.push_back(Attribute()); 00127 attr = &attributes.back(); 00128 00129 if(element == Attribute::VERTEX) 00130 attr->set(name, type, element); 00131 else if(element == Attribute::FACE) 00132 attr->set(name, type, element); 00133 else if(element == Attribute::CORNER) 00134 attr->set(name, type, element); 00135 00136 attr->reserve(mesh->verts.size(), mesh->triangles.size()); 00137 00138 return attr; 00139 } 00140 00141 Attribute *AttributeSet::find(ustring name) 00142 { 00143 foreach(Attribute& attr, attributes) 00144 if(attr.name == name) 00145 return &attr; 00146 00147 return NULL; 00148 } 00149 00150 void AttributeSet::remove(ustring name) 00151 { 00152 Attribute *attr = find(name); 00153 00154 if(attr) { 00155 list<Attribute>::iterator it; 00156 00157 for(it = attributes.begin(); it != attributes.end(); it++) { 00158 if(&*it == attr) { 00159 attributes.erase(it); 00160 return; 00161 } 00162 } 00163 } 00164 } 00165 00166 Attribute *AttributeSet::add(Attribute::Standard std, ustring name) 00167 { 00168 Attribute *attr = NULL; 00169 00170 if(name == ustring()) 00171 name = Attribute::standard_name(std); 00172 00173 if(std == Attribute::STD_VERTEX_NORMAL) 00174 attr = add(name, TypeDesc::TypeNormal, Attribute::VERTEX); 00175 else if(std == Attribute::STD_FACE_NORMAL) 00176 attr = add(name, TypeDesc::TypeNormal, Attribute::FACE); 00177 else if(std == Attribute::STD_UV) 00178 attr = add(name, TypeDesc::TypePoint, Attribute::CORNER); 00179 else if(std == Attribute::STD_GENERATED) 00180 attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX); 00181 else if(std == Attribute::STD_POSITION_UNDEFORMED) 00182 attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX); 00183 else if(std == Attribute::STD_POSITION_UNDISPLACED) 00184 attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX); 00185 else 00186 assert(0); 00187 00188 attr->std = std; 00189 00190 return attr; 00191 } 00192 00193 Attribute *AttributeSet::find(Attribute::Standard std) 00194 { 00195 foreach(Attribute& attr, attributes) 00196 if(attr.std == std) 00197 return &attr; 00198 00199 return NULL; 00200 } 00201 00202 void AttributeSet::remove(Attribute::Standard std) 00203 { 00204 Attribute *attr = find(std); 00205 00206 if(attr) { 00207 list<Attribute>::iterator it; 00208 00209 for(it = attributes.begin(); it != attributes.end(); it++) { 00210 if(&*it == attr) { 00211 attributes.erase(it); 00212 return; 00213 } 00214 } 00215 } 00216 } 00217 00218 Attribute *AttributeSet::find(AttributeRequest& req) 00219 { 00220 if(req.std == Attribute::STD_NONE) 00221 return find(req.name); 00222 else 00223 return find(req.std); 00224 } 00225 00226 void AttributeSet::reserve(int numverts, int numtris) 00227 { 00228 foreach(Attribute& attr, attributes) 00229 attr.reserve(numverts, numtris); 00230 } 00231 00232 void AttributeSet::clear() 00233 { 00234 attributes.clear(); 00235 } 00236 00237 /* AttributeRequest */ 00238 00239 AttributeRequest::AttributeRequest(ustring name_) 00240 { 00241 name = name_; 00242 std = Attribute::STD_NONE; 00243 00244 type = TypeDesc::TypeFloat; 00245 element = ATTR_ELEMENT_NONE; 00246 offset = 0; 00247 } 00248 00249 AttributeRequest::AttributeRequest(Attribute::Standard std_) 00250 { 00251 name = ustring(); 00252 std = std_; 00253 00254 type = TypeDesc::TypeFloat; 00255 element = ATTR_ELEMENT_NONE; 00256 offset = 0; 00257 } 00258 00259 /* AttributeRequestSet */ 00260 00261 AttributeRequestSet::AttributeRequestSet() 00262 { 00263 } 00264 00265 AttributeRequestSet::~AttributeRequestSet() 00266 { 00267 } 00268 00269 bool AttributeRequestSet::modified(const AttributeRequestSet& other) 00270 { 00271 if(requests.size() != other.requests.size()) 00272 return true; 00273 00274 for(size_t i = 0; i < requests.size(); i++) { 00275 bool found = false; 00276 00277 for(size_t j = 0; j < requests.size() && !found; j++) 00278 if(requests[i].name == other.requests[j].name && 00279 requests[i].std == other.requests[j].std) 00280 found = true; 00281 00282 if(!found) 00283 return true; 00284 } 00285 00286 return false; 00287 } 00288 00289 void AttributeRequestSet::add(ustring name) 00290 { 00291 foreach(AttributeRequest& req, requests) 00292 if(req.name == name) 00293 return; 00294 00295 requests.push_back(AttributeRequest(name)); 00296 } 00297 00298 void AttributeRequestSet::add(Attribute::Standard std) 00299 { 00300 foreach(AttributeRequest& req, requests) 00301 if(req.std == std) 00302 return; 00303 00304 requests.push_back(AttributeRequest(std)); 00305 } 00306 00307 void AttributeRequestSet::add(AttributeRequestSet& reqs) 00308 { 00309 foreach(AttributeRequest& req, reqs.requests) { 00310 if(req.std == Attribute::STD_NONE) 00311 add(req.name); 00312 else 00313 add(req.std); 00314 } 00315 } 00316 00317 bool AttributeRequestSet::find(ustring name) 00318 { 00319 foreach(AttributeRequest& req, requests) 00320 if(req.name == name) 00321 return true; 00322 00323 return false; 00324 } 00325 00326 bool AttributeRequestSet::find(Attribute::Standard std) 00327 { 00328 foreach(AttributeRequest& req, requests) 00329 if(req.std == std) 00330 return true; 00331 00332 return false; 00333 } 00334 00335 size_t AttributeRequestSet::size() 00336 { 00337 return requests.size(); 00338 } 00339 00340 void AttributeRequestSet::clear() 00341 { 00342 requests.clear(); 00343 } 00344 00345 CCL_NAMESPACE_END 00346