00001
00002
00003 #include "Iguana/Inventor/interface/IgSurfaceOperation.h"
00004 #include "Iguana/Inventor/interface/IgBSPTriangle.h"
00005 #include "Iguana/Inventor/interface/IgBSPTree.h"
00006 #include <Inventor/nodes/SoIndexedFaceSet.h>
00007 #include <Inventor/nodes/SoVertexProperty.h>
00008 #include <Inventor/nodes/SoShape.h>
00009 #include <Inventor/nodes/SoNode.h>
00010 #include <Inventor/SbLinear.h>
00011 #include <cassert>
00012 #include <map>
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 struct SbVec3fPtrComparison
00023 {
00024 bool operator()(const SbVec3f &a, const SbVec3f &b)
00025 {
00026 float diffX = a[0] - b[0];
00027 float diffY = a[1] - b[1];
00028 float diffZ = a[2] - b[2];
00029
00030 if (fabs (diffX) < MIN_POINT_DISTANCE)
00031 if (fabs (diffY) < MIN_POINT_DISTANCE)
00032 if (fabs (diffZ) < MIN_POINT_DISTANCE)
00033 return false;
00034 else return diffZ < 0;
00035 else return diffY < 0;
00036 else return diffX < 0;
00037 }
00038 };
00039
00040
00041 static SoIndexedFaceSet *
00042 listToNode (IgBSPTriangle::List *list)
00043 {
00044 SoIndexedFaceSet *indexedFaceSet = new SoIndexedFaceSet;
00045 SoVertexProperty *vertexProperty = new SoVertexProperty;
00046
00047 int lastIndex = 0;
00048 int j = 0;
00049
00050 std::map <const SbVec3f, int, SbVec3fPtrComparison> indicesMap;
00051
00052 int vertexIndices[4] = {0, 0, 0, -1};
00053 IgBSPTriangle::List::iterator end (list->end ());
00054 for (IgBSPTriangle::List::iterator i = list->begin ();
00055 i != end;
00056 i++)
00057 {
00058
00059
00060 for (int k = 0; k < 3; k++)
00061 {
00062 const SbVec3f &vertex = (*i)->v (k);
00063 if (indicesMap.find (vertex) == indicesMap.end ())
00064 {
00065 vertexProperty->vertex.setValues (lastIndex, 1, &vertex);
00066 indicesMap[vertex] = lastIndex++;
00067 }
00068 vertexIndices[k] = indicesMap[vertex];
00069 }
00070
00071 indexedFaceSet->coordIndex.setValues (j, 4, vertexIndices);
00072 j += 4;
00073 }
00074
00075
00076
00077
00078 indexedFaceSet->vertexProperty = vertexProperty;
00079
00080 return indexedFaceSet;
00081 }
00082
00083
00084
00085
00086 IgSurfaceOperation::IgSurfaceOperation (int operation)
00087 : m_operation (operation)
00088 {}
00089
00090 void
00091 IgSurfaceOperation::addNode (SoNode *node)
00092 {
00093 m_nodes.push_back (node);
00094 }
00095
00096 SoNode *
00097 IgSurfaceOperation::apply (void)
00098 {
00099 assert ("Multiple operand operations not supported yet" == 0);
00100
00101 return 0;
00102 }
00103
00104 SoNode *
00105 IgSurfaceOperation::apply (SoNode *a, SoNode *b)
00106 {
00107 IgBSPTree tree;
00108
00109
00110
00111 IgBSPTriangle::List trianglesInFront;
00112 IgBSPTriangle::List trianglesInBack;
00113 SoIndexedFaceSet *node = 0;
00114
00115 switch (m_operation)
00116 {
00117 case INTERSECTION:
00118 assert ("operation not supported" == 0);
00119 break;
00120
00121 case SUBTRACTION:
00122 assert ("operation not supported" == 0);
00123 break;
00124
00125 case UNION:
00126 assert ("operation not supported" == 0);
00127 break;
00128
00129 case SURFACE_1_IN_2:
00130 tree.addOnlyOneFace (a);
00131 tree.add (b);
00132 tree.intersect (a, 0, &trianglesInBack);
00133 node = listToNode (&trianglesInBack);
00134 break;
00135
00136 case SURFACE_2_IN_1:
00137 tree.addOnlyOneFace (b);
00138 tree.add (a);
00139 tree.intersect (b, 0, &trianglesInBack);
00140 node = listToNode (&trianglesInBack);
00141 break;
00142
00143 case SURFACE_1_OUT_2:
00144 tree.addOnlyOneFace (a);
00145 tree.add (b);
00146 tree.intersect (a, &trianglesInFront, 0);
00147 node = listToNode (&trianglesInFront);
00148 break;
00149
00150 case SURFACE_2_OUT_1:
00151 tree.addOnlyOneFace (b);
00152 tree.add (a);
00153 tree.intersect (b, &trianglesInFront, 0);
00154 node = listToNode (&trianglesInFront);
00155 break;
00156 }
00157 IgBSPTriangle::unrefAndDeleteTriangles (trianglesInFront);
00158 IgBSPTriangle::unrefAndDeleteTriangles (trianglesInBack);
00159
00160 return node;
00161 }