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/boolop/intern/BOP_MaterialContainer.cpp')
-rw-r--r--intern/boolop/intern/BOP_MaterialContainer.cpp242
1 files changed, 242 insertions, 0 deletions
diff --git a/intern/boolop/intern/BOP_MaterialContainer.cpp b/intern/boolop/intern/BOP_MaterialContainer.cpp
new file mode 100644
index 00000000000..b8f38b35651
--- /dev/null
+++ b/intern/boolop/intern/BOP_MaterialContainer.cpp
@@ -0,0 +1,242 @@
+/**
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <iostream>
+#include "BOP_MaterialContainer.h"
+#include "BOP_MathUtils.h"
+#include "MEM_SmartPtr.h"
+
+/**
+ * Constructs a new material container.
+ */
+BOP_MaterialContainer::BOP_MaterialContainer()
+{
+ m_interpFunc = NULL;
+}
+
+/**
+ * Destroys a material container.
+ */
+BOP_MaterialContainer::~BOP_MaterialContainer()
+{
+}
+
+/**
+ * Adds a new material to this container.
+ * @param m material material object to add.
+ * @return the new material index.
+ */
+BOP_Index BOP_MaterialContainer::addMaterial(BOP_Material m)
+{
+ m_materialList.push_back(m);
+ return m_materialList.size()-1;
+}
+
+/**
+ * Updates the interpolation function of this container.
+ * @param interpFunc the interpolation function.
+ */
+void BOP_MaterialContainer::setInterpFunc(CSG_InterpolateUserFaceVertexDataFunc interpFunc)
+{
+ m_interpFunc = interpFunc;
+}
+
+/**
+ * Returns the material list.
+ * @return
+ */
+BOP_Materials& BOP_MaterialContainer::getMaterialList()
+{
+ return m_materialList;
+}
+
+/**
+ * Returns the material with the specified index.
+ * @param index material index.
+ * @return material with the specified index.
+ */
+BOP_Material* BOP_MaterialContainer::getMaterial(BOP_Index index)
+{
+ return index < m_materialList.size() ? &(m_materialList[index]) : NULL;
+}
+
+/**
+ * Returns the pointer to face material specified by index.
+ * @param index material index.
+ * @return pointer to face material.
+ */
+char* BOP_MaterialContainer::getFaceMaterial(BOP_Index index)
+{
+ if (index < m_materialList.size())
+ return m_materialList[index].getFaceMaterial();
+ else return NULL;
+}
+
+/**
+ * Returns a pointer to face vertex material, if is the material not exist, then
+ * returns an interpoled material.
+ * @param mesh original mesh data.
+ * @param originalFaceIndex index to the original mesh face.
+ * @param point point who needs a material.
+ * @param faceVertexMaterial pointer to mem region where the material will be
+ * saved.
+ * @return pointer to the face vertex material.
+ */
+char* BOP_MaterialContainer::getFaceVertexMaterial(BOP_Mesh *mesh,
+ BOP_Index originalFaceIndex,
+ MT_Point3 point,
+ char* faceVertexMaterial)
+{
+ if (originalFaceIndex>=m_materialList.size()) return NULL;
+
+ BOP_Material& material = m_materialList[originalFaceIndex];
+
+ if (material.isQuad()) {
+
+ BOP_Face *face1 = mesh->getFace(material.getOriginalFace());
+ BOP_Face *face2 = mesh->getFace(material.getOriginalFace()+1);
+
+ if (!face1 || !face2) return NULL;
+
+ // Search original point
+ for (unsigned int i=0;i<face1->size();i++) {
+ if (point == mesh->getVertex(face1->getVertex(i))->getPoint()) {
+ return material.getOriginalFaceVertexMaterial(face1->getVertex(i));
+ }
+ }
+ for (unsigned int i=0;i<face2->size();i++) {
+ if (point == mesh->getVertex(face2->getVertex(i))->getPoint()) {
+ return material.getOriginalFaceVertexMaterial(face2->getVertex(i));
+ }
+ }
+ // wich is the half quad where the point is?
+ MT_Vector3 N = face1->getPlane().Normal();
+ MT_Point3 p0 = mesh->getVertex(face1->getVertex(0))->getPoint();
+ MT_Point3 q(p0.x()+N.x(),p0.y()+N.y(),p0.z()+N.z());
+ MT_Point3 p2 = mesh->getVertex(face1->getVertex(1))->getPoint();
+ MT_Plane3 plane(p0,p2,q);
+
+ if (BOP_sign(plane.signedDistance(point))==-1) {
+ // first half quad
+ faceVertexMaterial = interpolateMaterial(mesh, face1, material, point, faceVertexMaterial);
+ }
+ else {
+ // second half quad
+ faceVertexMaterial = interpolateMaterial(mesh, face2, material, point, faceVertexMaterial);
+ }
+ }
+ else {
+ BOP_Face *face1 = mesh->getFace(material.getOriginalFace());
+
+ if (!face1) return NULL;
+
+ // Search original point
+ for (unsigned int i=0;i<face1->size();i++) {
+ if (point == mesh->getVertex(face1->getVertex(i))->getPoint())
+ return material.getOriginalFaceVertexMaterial(face1->getVertex(i));
+ }
+
+ faceVertexMaterial = interpolateMaterial(mesh, face1, material, point, faceVertexMaterial);
+ }
+
+ return faceVertexMaterial;
+}
+
+/**
+ * Performs vertex data interpolation.
+ * @param mesh original mesh data.
+ * @param face face used to interpolate an interior face point material
+ * @param material face material, input data for implementation.
+ * @param point interpolated point.
+ * @param faceVertexMaterial pointer to memory region.
+ * @return pointer to face vertex material.
+ */
+char* BOP_MaterialContainer::interpolateMaterial(BOP_Mesh* mesh,
+ BOP_Face* face,
+ BOP_Material& material,
+ MT_Point3 point,
+ char* faceVertexMaterial)
+{
+ // (p1)-----(I)------(p2)
+ // \ | /
+ // \ | /
+ // \ | /
+ // \ (point) /
+ // \ | /
+ // \ | /
+ // \ | /
+ // (p3)
+
+ MT_Point3 p1 = mesh->getVertex(face->getVertex(0))->getPoint();
+ MT_Point3 p2 = mesh->getVertex(face->getVertex(1))->getPoint();
+ MT_Point3 p3 = mesh->getVertex(face->getVertex(2))->getPoint();
+ MT_Point3 I = BOP_4PointIntersect(p1, p2, p3, point);
+ MT_Scalar epsilon0 = 1.0-BOP_EpsilonDistance(p1, p2, I);
+ MT_Scalar epsilon1 = 1.0-BOP_EpsilonDistance(I, p3, point);
+
+ // Interpolate data
+ if (m_interpFunc) {
+ // temporal data
+ char* faceVertexMaterialTemp = new char[material.getFaceVertexWidth()];
+
+ (*m_interpFunc)(material.getOriginalFaceVertexMaterial(face->getVertex(0)),
+ material.getOriginalFaceVertexMaterial(face->getVertex(1)),
+ faceVertexMaterialTemp,
+ epsilon0);
+
+ (*m_interpFunc)(faceVertexMaterialTemp,
+ material.getOriginalFaceVertexMaterial(face->getVertex(2)),
+ faceVertexMaterial,
+ epsilon1);
+
+ // free temporal data
+ delete[] faceVertexMaterialTemp;
+
+ }
+ else faceVertexMaterial = NULL;
+
+ // return the result
+ return (char*) faceVertexMaterial;
+}
+
+/**
+ * Implements operator <<
+ */
+ostream &operator<<(ostream &stream, BOP_MaterialContainer *mc)
+{
+ stream << "***[ Material List ]***********************************************" << endl;
+ BOP_IT_Materials it;
+ for (it=mc->getMaterialList().begin();it!=mc->getMaterialList().end();++it) {
+ stream << "[" << it - mc->getMaterialList().begin() << "] ";
+ stream << &(*it);
+ }
+ stream << "*******************************************************************" << endl;
+ return stream;
+}