Blender V2.61 - r43446

attribute.cpp

Go to the documentation of this file.
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