Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlGraphics/EdgeExtractor.hpp>
00033 #include <vlGraphics/Rendering.hpp>
00034 #include <vlGraphics/SceneManager.hpp>
00035 #include <vlGraphics/RenderQueue.hpp>
00036 #include <vlCore/Log.hpp>
00037 #include <vlGraphics/Array.hpp>
00038 #include <vlGraphics/Geometry.hpp>
00039
00040 using namespace vl;
00041
00042
00043 void EdgeExtractor::addEdge(std::set<EdgeExtractor::Edge>& edges, const EdgeExtractor::Edge& e, const fvec3& n)
00044 {
00045 std::set<EdgeExtractor::Edge>::iterator it = edges.find(e);
00046 if (it != edges.end())
00047 {
00048 VL_CHECK(!it->normal1().isNull())
00049 if (mWarnNonManifold && !it->normal2().isNull())
00050 vl::Log::error("EdgeExtractor: non-manifold mesh detected!\n");
00051 EdgeExtractor::Edge edge = e;
00052 edge.setNormal1(it->normal1());
00053 edge.setNormal2(n);
00054 edges.erase( it );
00055 edges.insert(edge);
00056 }
00057 else
00058 {
00059 VL_CHECK(!n.isNull());
00060 EdgeExtractor::Edge edge = e;
00061 edge.setNormal1(n);
00062 edges.insert(edge);
00063 }
00064 }
00065
00067 void EdgeExtractor::extractEdges(Geometry* geom)
00068 {
00069 ArrayAbstract* verts = geom->vertexArray() ? geom->vertexArray() : geom->vertexAttribArray(vl::VA_Position) ? geom->vertexAttribArray(vl::VA_Position)->data() : NULL;
00070
00071
00072
00073
00074 if (!verts)
00075 {
00076 vl::Log::error("EdgeExtractor::extractEdges(geom): 'geom' must have a vertex array of type ArrayFloat3.\n");
00077 return;
00078 }
00079
00080 std::set<Edge> edges;
00081
00082
00083 for(int iprim=0; iprim<geom->drawCalls()->size(); ++iprim)
00084 {
00085 DrawCall* prim = geom->drawCalls()->at(iprim);
00086
00087 for(TriangleIterator trit = prim->triangleIterator(); trit.hasNext(); trit.next())
00088 {
00089 size_t a = trit.a();
00090 size_t b = trit.b();
00091 size_t c = trit.c();
00092 if (a == b || b == c || c == a)
00093 continue;
00094
00095 fvec3 v0 = (fvec3)verts->getAsVec3(a);
00096 fvec3 v1 = (fvec3)verts->getAsVec3(b) - v0;
00097 fvec3 v2 = (fvec3)verts->getAsVec3(c) - v0;
00098 fvec3 n = cross(v1,v2).normalize();
00099 if (n.isNull())
00100 continue;
00101 addEdge(edges, Edge( (fvec3)verts->getAsVec3(a), (fvec3)verts->getAsVec3(b) ), n );
00102 addEdge(edges, Edge( (fvec3)verts->getAsVec3(b), (fvec3)verts->getAsVec3(c) ), n );
00103 addEdge(edges, Edge( (fvec3)verts->getAsVec3(c), (fvec3)verts->getAsVec3(a) ), n );
00104 }
00105 }
00106
00107 for(std::set<Edge>::iterator it = edges.begin(); it != edges.end(); ++it)
00108 {
00109 Edge e = *it;
00110
00111 if (e.normal2().isNull())
00112 e.setIsCrease(true);
00113 else
00114
00115 {
00116 float cos1 = dot(e.normal1(), e.normal2());
00117 cos1 = vl::clamp(cos1,-1.0f,+1.0f);
00118
00119 float a1 = acos(cos1) / fPi * 180.0f;
00120 if( a1 > creaseAngle() )
00121 e.setIsCrease(true);
00122 }
00123 mEdges.push_back(e);
00124 }
00125 }
00126
00127 ref<Geometry> EdgeExtractor::generateEdgeGeometry() const
00128 {
00129 ref<Geometry> geom = new Geometry;
00130 geom->setBufferObjectEnabled(false);
00131 ref<ArrayFloat3> vert_array = new ArrayFloat3;
00132 geom->setVertexArray(vert_array.get());
00133 #ifdef SHOW_NORMALS
00134 vert_array->resize(edges().size()*6);
00135 #else
00136 vert_array->resize(edges().size()*2);
00137 #endif
00138 for(unsigned i=0; i<edges().size(); ++i)
00139 {
00140 vert_array->at(i*2+0) = edges()[i].vertex1();
00141 vert_array->at(i*2+1) = edges()[i].vertex2();
00142 }
00143 #ifdef SHOW_NORMALS
00144 int start = edges().size()*2;
00145 for(unsigned i=0; i<edges().size(); ++i)
00146 {
00147 fvec3 v = (edges()[i].vertex1() + edges()[i].vertex2()) * 0.5f;
00148 vert_array->at(start+i*2+0) = v;
00149 vert_array->at(start+i*2+1) = v + edges()[i].normal1()*0.25f;
00150 }
00151 start = edges().size()*4;
00152 for(unsigned i=0; i<edges().size(); ++i)
00153 {
00154 fvec3 v = (edges()[i].vertex1() + edges()[i].vertex2()) * 0.5f;
00155 vert_array->at(start+i*2+0) = v;
00156 vert_array->at(start+i*2+1) = v + edges()[i].normal2()*0.25f;
00157 }
00158 #endif
00159 geom->drawCalls()->push_back( new vl::DrawArrays(vl::PT_LINES, 0, (int)vert_array->size()) );
00160 return geom;
00161 }
00162
00163 bool EdgeExtractor::extractEdges(Actor* actor)
00164 {
00165 Geometry* geom = cast<Geometry>(actor->lod(0));
00166 if (geom)
00167 extractEdges(geom);
00168 return geom != NULL;
00169 }
00170
00171 void EdgeExtractor::extractEdges(ActorCollection* actors)
00172 {
00173 for(int i=0; i<actors->size(); ++i)
00174 {
00175 Geometry* geom = cast<Geometry>(actors->at(i)->lod(0));
00176 if (geom)
00177 extractEdges(geom);
00178 }
00179 }
00180
00181 void EdgeExtractor::extractEdges(SceneManager* scene_manager)
00182 {
00183 ref<ActorCollection> actors = new ActorCollection;
00184 scene_manager->extractActors(*actors);
00185 extractEdges(actors.get());
00186 }
00187
00188 void EdgeExtractor::extractEdges(Rendering* rendering)
00189 {
00190 for(int i=0; i<rendering->sceneManagers()->size(); ++i)
00191 extractEdges(rendering->sceneManagers()->at(i));
00192 }
00193