00001 #include "SIGEL_Visualisation/SIG_RobotRenderer.h" 00002 #include "SIGEL_Tools/SIG_TypeConverter.h" 00003 00004 using namespace SIGEL_Tools; 00005 00006 namespace SIGEL_Visualisation 00007 { 00008 00009 SIG_RobotRenderer::SIG_RobotRenderer(SIGEL_Robot::SIG_Robot const &robot) 00010 : SIG_Renderer( robot.getLinkIter().count() + robot.getNrOfPoints(), robot.getNrOfPoints() ), 00011 robot(robot) 00012 { 00013 QDictIterator<SIGEL_Robot::SIG_Link> linkIter = robot.getLinkIter(); 00014 00015 linkIter.toFirst(); 00016 00017 while (linkIter.current()) 00018 { 00019 SIGEL_Robot::SIG_Link &actLink = *linkIter.current(); 00020 00021 int number = actLink.getNumber(); 00022 QString name = actLink.getName(); 00023 00024 SIG_VisualSceneObject *newSceneObject = new SIG_VisualSceneObject(number, name); 00025 newSceneObject->setColor( actLink.getMaterial()->getColour() ); 00026 00027 sceneObjects.insert( number, newSceneObject ); 00028 00029 ++linkIter; 00030 }; 00031 00032 buildDisplayLists(); 00033 00034 setPointsVisible( false ); 00035 }; 00036 00037 SIG_RobotRenderer::~SIG_RobotRenderer() 00038 { }; 00039 00040 void SIG_RobotRenderer::buildDisplayLists() 00041 { 00042 QDictIterator<SIGEL_Robot::SIG_Link> linkIter = robot.getLinkIter(); 00043 00044 int nextPointIndex = robot.getLinkIter().count(); 00045 int nextFloatingIndex = 0; 00046 00047 while (linkIter.current()) 00048 { 00049 SIGEL_Robot::SIG_Link &actLink = *linkIter.current(); 00050 00051 int linkNumber = actLink.getNumber(); 00052 GLuint linkIndex = static_cast<GLuint>(linkNumber); 00053 GLuint actListIndex = linkIndex + displayListsOffset; 00054 00055 glNewList(actListIndex, GL_COMPILE); 00056 00057 SIGEL_Robot::SIG_Geometry const *actGeometry = actLink.getGeometry(); 00058 SIGEL_Robot::SIG_GeometryIterator actGeoIter(actGeometry); 00059 00060 glFrontFace( GL_CCW ); 00061 00062 while (actGeoIter.valid()) 00063 { 00064 SIGEL_Robot::SIG_Polygon const &actPolygon = actGeoIter.current(); 00065 00066 DL_vector vertex0 = actPolygon.getVertex( 0 ); 00067 DL_vector vertex1 = actPolygon.getVertex( 1 ); 00068 DL_vector vertex2 = actPolygon.getVertex( 2 ); 00069 00070 DL_vector u = vertex0; 00071 u.minusis( &vertex1 ); 00072 00073 DL_vector v = vertex2; 00074 v.minusis( &vertex1 ); 00075 00076 DL_vector polygonNormal; 00077 00078 v.crossprod( &u, &polygonNormal ); 00079 00080 glNormal3f( static_cast<GLfloat>( polygonNormal.get(0) ), 00081 static_cast<GLfloat>( polygonNormal.get(1) ), 00082 static_cast<GLfloat>( polygonNormal.get(2) ) ); 00083 00084 glBegin(GL_POLYGON); 00085 for (int i=0; i<actPolygon.getNumVertices(); i++) 00086 { 00087 DL_vector actVertex = actPolygon.getVertex(i); 00088 glVertex3d( static_cast<GLdouble>(actVertex.get(0)), 00089 static_cast<GLdouble>(actVertex.get(1)), 00090 static_cast<GLdouble>(actVertex.get(2)) ); 00091 }; 00092 glEnd(); 00093 00094 actGeoIter.next(); 00095 }; 00096 00097 glEndList(); 00098 00099 QDictIterator<DL_vector> pointIter = actLink.getPointIter(); 00100 00101 pointIter.toFirst(); 00102 00103 while (pointIter.current()) 00104 { 00105 GLuint pointIndex = static_cast<GLuint>( nextPointIndex ); 00106 00107 GLuint actListIndex = pointIndex + displayListsOffset; 00108 00109 DL_vector pointPosition = *pointIter.current(); 00110 00111 glNewList( actListIndex, GL_COMPILE ); 00112 glPointSize( 5 ); 00113 glBegin( GL_POINTS ); 00114 glVertex3d( static_cast<GLdouble>(pointPosition.get(0)), 00115 static_cast<GLdouble>(pointPosition.get(1)), 00116 static_cast<GLdouble>(pointPosition.get(2)) ); 00117 glEnd(); 00118 glEndList(); 00119 00120 SIG_VisualSceneObject *newPointSceneObject = new SIG_VisualSceneObject( linkNumber, 00121 pointIter.currentKey() ); 00122 00123 SIG_FloatingText *newFloatingText = new SIG_FloatingText( 0, 0, pointIter.currentKey() ); 00124 00125 newPointSceneObject->setFloatingText( newFloatingText ); 00126 00127 DL_vector linkColor = actLink.getMaterial()->getColour(); 00128 00129 for (int i=0; i<3; i++) 00130 { 00131 double newValue = linkColor.get(i) - 0.3; 00132 newValue = ( newValue < 0 ) ? 0 : newValue; 00133 linkColor.set( i, newValue ); 00134 }; 00135 00136 newPointSceneObject->setColor( linkColor ); 00137 00138 sceneObjects.insert( nextPointIndex, 00139 newPointSceneObject ); 00140 00141 floatingTexts.insert( nextFloatingIndex, 00142 newFloatingText ); 00143 00144 nextPointIndex++; 00145 nextFloatingIndex++; 00146 ++pointIter; 00147 }; 00148 00149 ++linkIter; 00150 }; 00151 00152 }; 00153 00154 void SIG_RobotRenderer::render() 00155 { 00156 renderSceneObjects(); 00157 00158 for (GLuint i=static_cast<GLuint>(robot.getLinkIter().count()); i<noOfObjects; i++) 00159 { 00160 QArray< GLfloat > buffer( 3 ); 00161 buffer.fill( 0 ); 00162 00163 glFeedbackBuffer( 3, GL_2D, buffer.data() ); 00164 glRenderMode(GL_FEEDBACK); 00165 00166 glPushMatrix(); 00167 sceneObjects[i]->applyTransformation(); 00168 00169 glCallList( displayListsOffset + i ); 00170 glPopMatrix(); 00171 00172 glRenderMode(GL_RENDER); 00173 00174 if ( buffer[0] == GL_POINT_TOKEN ) 00175 { 00176 sceneObjects[i]->getFloatingText()->rendered = true; 00177 sceneObjects[i]->getFloatingText()->xPos = static_cast<int>( buffer[1] ); 00178 sceneObjects[i]->getFloatingText()->yPos = static_cast<int>( buffer[2] ); 00179 } 00180 else 00181 sceneObjects[i]->getFloatingText()->rendered = false; 00182 }; 00183 }; 00184 00185 QString SIG_RobotRenderer::exportToPovray() 00186 { 00187 return exportSceneObjectsToPovray(); 00188 }; 00189 00190 QString SIG_RobotRenderer::createPovrayDeclarations() 00191 { 00192 QString declarationsString; 00193 00194 QTextStream stream( &declarationsString, IO_WriteOnly ); 00195 00196 QDictIterator<SIGEL_Robot::SIG_Material> materialIter = robot.getMaterialIter(); 00197 00198 while (materialIter.current()) 00199 { 00200 SIGEL_Robot::SIG_Material &actMaterial = *materialIter.current(); 00201 00202 stream << "#declare " 00203 << actMaterial.getName() 00204 << " = texture {\n" 00205 << " pigment { rgb " 00206 << SIG_Renderer::vectorToPovray( SIG_TypeConverter::toColumnVector( actMaterial.getColour() ) ) 00207 << " }\n" 00208 << " finish { ambient rgb " 00209 << SIG_Renderer::vectorToPovray( SIG_TypeConverter::toColumnVector( actMaterial.getColour() ) ) 00210 << "\n" 00211 << " diffuse 1 }\n" 00212 << "}\n" 00213 << "\n"; 00214 00215 ++materialIter; 00216 }; 00217 00218 QString pointDataString; 00219 QTextStream pointDataStream( &pointDataString, IO_WriteOnly ); 00220 00221 QDictIterator<SIGEL_Robot::SIG_Link> linkIter = robot.getLinkIter(); 00222 00223 while (linkIter.current()) 00224 { 00225 SIGEL_Robot::SIG_Link &actLink = *linkIter.current(); 00226 00227 int linkNumber = actLink.getNumber(); 00228 00229 QString polygonDataString; 00230 QTextStream polygonDataStream( &polygonDataString, IO_WriteOnly ); 00231 00232 stream << "#declare " 00233 << actLink.getName() 00234 << " = mesh {\n"; 00235 00236 SIGEL_Robot::SIG_Geometry const *actGeometry = actLink.getGeometry(); 00237 SIGEL_Robot::SIG_GeometryIterator actGeoIter(actGeometry); 00238 00239 while (actGeoIter.valid()) 00240 { 00241 SIGEL_Robot::SIG_Polygon const &actPolygon = actGeoIter.current(); 00242 00243 NEWMAT::ColumnVector firstVertex = SIG_TypeConverter::toColumnVector( actPolygon.getVertex( 0 ) ); 00244 00245 NEWMAT::ColumnVector secondVertex = SIG_TypeConverter::toColumnVector( actPolygon.getVertex( 1 ) ); 00246 00247 for ( int i=2; i < actPolygon.getNumVertices(); i++ ) 00248 { 00249 NEWMAT::ColumnVector thirdVertex = SIG_TypeConverter::toColumnVector( actPolygon.getVertex( i ) ); 00250 00251 polygonDataStream << " triangle {\n"; 00252 00253 polygonDataStream << " " 00254 << SIG_Renderer::vectorToPovray( firstVertex ) 00255 << ", " 00256 << SIG_Renderer::vectorToPovray( secondVertex ) 00257 << ", " 00258 << SIG_Renderer::vectorToPovray( thirdVertex ) 00259 << "\n" 00260 << " }\n"; 00261 00262 secondVertex = thirdVertex; 00263 }; 00264 00265 actGeoIter.next(); 00266 }; 00267 00268 QDictIterator<DL_vector> pointIter = actLink.getPointIter(); 00269 00270 pointIter.toFirst(); 00271 00272 while (pointIter.current()) 00273 { 00274 NEWMAT::ColumnVector pointPosition = SIG_TypeConverter::toColumnVector( *pointIter.current() ); 00275 00276 NEWMAT::ColumnVector linkColor = SIG_TypeConverter::toColumnVector( actLink.getMaterial()->getColour() ); 00277 00278 for (int i=1; i<=3; i++) 00279 { 00280 double newValue = linkColor( i ) - 0.3; 00281 newValue = ( newValue < 0 ) ? 0 : newValue; 00282 linkColor( i ) = newValue; 00283 }; 00284 00285 pointDataStream << "#declare " 00286 << pointIter.currentKey() 00287 << " = sphere {\n" 00288 << " " 00289 << vectorToPovray( pointPosition ) 00290 << ", 0.05\n" 00291 << " texture {\n" 00292 << " " 00293 << actLink.getMaterial()->getName() 00294 << "\n" 00295 << " pigment { rgb " 00296 << vectorToPovray( linkColor ) 00297 << " }\n" 00298 << " }\n" 00299 << "}\n" 00300 << "\n"; 00301 00302 ++pointIter; 00303 }; 00304 00305 stream << polygonDataString 00306 << "\n" 00307 << " texture { " 00308 << actLink.getMaterial()->getName() 00309 << " }\n" 00310 << "}\n" 00311 << "\n"; 00312 ++linkIter; 00313 }; 00314 00315 stream << pointDataString; 00316 00317 return declarationsString; 00318 }; 00319 00320 void SIG_RobotRenderer::setPointsVisible( bool visible ) 00321 { 00322 for (int i = robot.getLinkIter().count(); i < noOfObjects; i++ ) 00323 sceneObjects[i]->setVisible( visible ); 00324 }; 00325 00326 }