Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/EdgeExtractor.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
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   // mic fixme:
00072   // here the bottle-neck seems to be the continuous allocation/deallocation and insertion/search time,
00073   // maybe a memory-pool-managed hash table would help?
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   // iterate all primitives
00083   for(int iprim=0; iprim<geom->drawCalls()->size(); ++iprim)
00084   {
00085     DrawCall* prim = geom->drawCalls()->at(iprim);
00086     // iterate triangles (if present)
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       // compute normal
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     // boundary edge
00111     if (e.normal2().isNull())
00112       e.setIsCrease(true);
00113     else
00114     // crease edge
00115     {
00116       float cos1 = dot(e.normal1(), e.normal2());
00117       cos1 = vl::clamp(cos1,-1.0f,+1.0f);
00118       // return value in the interval [0,pi] radians
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 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:36.
Permission is granted to use this page to write and publish articles regarding Visualization Library.