Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/attribute.cpp')
-rw-r--r--intern/cycles/render/attribute.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
new file mode 100644
index 00000000000..815478cb733
--- /dev/null
+++ b/intern/cycles/render/attribute.cpp
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mesh.h"
+#include "attribute.h"
+
+#include "util_debug.h"
+#include "util_foreach.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Attribute */
+
+void Attribute::set(ustring name_, TypeDesc type_, Element element_)
+{
+ name = name_;
+ type = type_;
+ element = element_;
+ std = STD_NONE;
+
+ /* string and matrix not supported! */
+ assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
+ type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
+ type == TypeDesc::TypeNormal);
+}
+
+void Attribute::reserve(int numverts, int numtris)
+{
+ buffer.resize(buffer_size(numverts, numtris), 0);
+}
+
+size_t Attribute::data_sizeof()
+{
+ return type.size();
+}
+
+size_t Attribute::element_size(int numverts, int numtris)
+{
+ if(element == VERTEX)
+ return numverts;
+ else if(element == FACE)
+ return numtris;
+ else
+ return numtris*3;
+}
+
+size_t Attribute::buffer_size(int numverts, int numtris)
+{
+ return element_size(numverts, numtris)*data_sizeof();
+}
+
+bool Attribute::same_storage(TypeDesc a, TypeDesc b)
+{
+ if(a == b)
+ return true;
+
+ if(a == TypeDesc::TypeColor || a == TypeDesc::TypePoint ||
+ a == TypeDesc::TypeVector || a == TypeDesc::TypeNormal)
+ if(b == TypeDesc::TypeColor || b == TypeDesc::TypePoint ||
+ b == TypeDesc::TypeVector || b == TypeDesc::TypeNormal)
+ return true;
+
+ return false;
+}
+
+ustring Attribute::standard_name(Attribute::Standard std)
+{
+ if(std == Attribute::STD_VERTEX_NORMAL)
+ return ustring("N");
+ else if(std == Attribute::STD_FACE_NORMAL)
+ return ustring("Ng");
+ else if(std == Attribute::STD_UV)
+ return ustring("uv");
+ else if(std == Attribute::STD_GENERATED)
+ return ustring("generated");
+ else if(std == Attribute::STD_POSITION_UNDEFORMED)
+ return ustring("undeformed");
+ else if(std == Attribute::STD_POSITION_UNDISPLACED)
+ return ustring("undisplaced");
+
+ return ustring();
+}
+
+/* Attribute Set */
+
+AttributeSet::AttributeSet(Mesh *mesh_)
+{
+ mesh = mesh_;
+}
+
+AttributeSet::~AttributeSet()
+{
+}
+
+Attribute *AttributeSet::add(ustring name, TypeDesc type, Attribute::Element element)
+{
+ Attribute *attr = find(name);
+
+ if(attr) {
+ /* return if same already exists */
+ if(attr->type == type && attr->element == element)
+ return attr;
+
+ /* overwrite attribute with same name but different type/element */
+ remove(name);
+ }
+
+ attributes.push_back(Attribute());
+ attr = &attributes.back();
+
+ if(element == Attribute::VERTEX)
+ attr->set(name, type, element);
+ else if(element == Attribute::FACE)
+ attr->set(name, type, element);
+ else if(element == Attribute::CORNER)
+ attr->set(name, type, element);
+
+ attr->reserve(mesh->verts.size(), mesh->triangles.size());
+
+ return attr;
+}
+
+Attribute *AttributeSet::find(ustring name)
+{
+ foreach(Attribute& attr, attributes)
+ if(attr.name == name)
+ return &attr;
+
+ return NULL;
+}
+
+void AttributeSet::remove(ustring name)
+{
+ Attribute *attr = find(name);
+
+ if(attr) {
+ list<Attribute>::iterator it;
+
+ for(it = attributes.begin(); it != attributes.end(); it++) {
+ if(&*it == attr) {
+ attributes.erase(it);
+ return;
+ }
+ }
+ }
+}
+
+Attribute *AttributeSet::add(Attribute::Standard std, ustring name)
+{
+ Attribute *attr = NULL;
+
+ if(name == ustring())
+ name = Attribute::standard_name(std);
+
+ if(std == Attribute::STD_VERTEX_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, Attribute::VERTEX);
+ else if(std == Attribute::STD_FACE_NORMAL)
+ attr = add(name, TypeDesc::TypeNormal, Attribute::FACE);
+ else if(std == Attribute::STD_UV)
+ attr = add(name, TypeDesc::TypePoint, Attribute::CORNER);
+ else if(std == Attribute::STD_GENERATED)
+ attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
+ else if(std == Attribute::STD_POSITION_UNDEFORMED)
+ attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
+ else if(std == Attribute::STD_POSITION_UNDISPLACED)
+ attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
+ else
+ assert(0);
+
+ attr->std = std;
+
+ return attr;
+}
+
+Attribute *AttributeSet::find(Attribute::Standard std)
+{
+ foreach(Attribute& attr, attributes)
+ if(attr.std == std)
+ return &attr;
+
+ return NULL;
+}
+
+void AttributeSet::remove(Attribute::Standard std)
+{
+ Attribute *attr = find(std);
+
+ if(attr) {
+ list<Attribute>::iterator it;
+
+ for(it = attributes.begin(); it != attributes.end(); it++) {
+ if(&*it == attr) {
+ attributes.erase(it);
+ return;
+ }
+ }
+ }
+}
+
+Attribute *AttributeSet::find(AttributeRequest& req)
+{
+ if(req.std == Attribute::STD_NONE)
+ return find(req.name);
+ else
+ return find(req.std);
+}
+
+void AttributeSet::reserve(int numverts, int numtris)
+{
+ foreach(Attribute& attr, attributes)
+ attr.reserve(numverts, numtris);
+}
+
+void AttributeSet::clear()
+{
+ attributes.clear();
+}
+
+/* AttributeRequest */
+
+AttributeRequest::AttributeRequest(ustring name_)
+{
+ name = name_;
+ std = Attribute::STD_NONE;
+
+ type = TypeDesc::TypeFloat;
+ element = ATTR_ELEMENT_NONE;
+ offset = 0;
+}
+
+AttributeRequest::AttributeRequest(Attribute::Standard std_)
+{
+ name = ustring();
+ std = std_;
+
+ type = TypeDesc::TypeFloat;
+ element = ATTR_ELEMENT_NONE;
+ offset = 0;
+}
+
+/* AttributeRequestSet */
+
+AttributeRequestSet::AttributeRequestSet()
+{
+}
+
+AttributeRequestSet::~AttributeRequestSet()
+{
+}
+
+bool AttributeRequestSet::modified(const AttributeRequestSet& other)
+{
+ if(requests.size() != other.requests.size())
+ return true;
+
+ for(size_t i = 0; i < requests.size(); i++) {
+ bool found = false;
+
+ for(size_t j = 0; j < requests.size() && !found; j++)
+ if(requests[i].name == other.requests[j].name &&
+ requests[i].std == other.requests[j].std)
+ found = true;
+
+ if(!found)
+ return true;
+ }
+
+ return false;
+}
+
+void AttributeRequestSet::add(ustring name)
+{
+ foreach(AttributeRequest& req, requests)
+ if(req.name == name)
+ return;
+
+ requests.push_back(AttributeRequest(name));
+}
+
+void AttributeRequestSet::add(Attribute::Standard std)
+{
+ foreach(AttributeRequest& req, requests)
+ if(req.std == std)
+ return;
+
+ requests.push_back(AttributeRequest(std));
+}
+
+void AttributeRequestSet::add(AttributeRequestSet& reqs)
+{
+ foreach(AttributeRequest& req, reqs.requests) {
+ if(req.std == Attribute::STD_NONE)
+ add(req.name);
+ else
+ add(req.std);
+ }
+}
+
+bool AttributeRequestSet::find(ustring name)
+{
+ foreach(AttributeRequest& req, requests)
+ if(req.name == name)
+ return true;
+
+ return false;
+}
+
+bool AttributeRequestSet::find(Attribute::Standard std)
+{
+ foreach(AttributeRequest& req, requests)
+ if(req.std == std)
+ return true;
+
+ return false;
+}
+
+size_t AttributeRequestSet::size()
+{
+ return requests.size();
+}
+
+void AttributeRequestSet::clear()
+{
+ requests.clear();
+}
+
+CCL_NAMESPACE_END
+