void ccOctree::drawMeOnly(CC_DRAW_CONTEXT& context) { if (m_thePointsAndTheirCellCodes.empty()) return; if (MACRO_Draw3D(context)) { bool pushName = MACRO_DrawEntityNames(context); if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); } assert(m_displayedLevel < 256); RenderOctreeAs(m_displayType,this,static_cast<uchar>(m_displayedLevel),m_theAssociatedCloudAsGPC,m_glListID,m_shouldBeRefreshed); if (m_shouldBeRefreshed) m_shouldBeRefreshed = false; if (pushName) glPopName(); } }
void ccKdTree::drawMeOnly(CC_DRAW_CONTEXT& context) { if (!m_associatedGenericCloud || !m_root) return; if (MACRO_Draw3D(context)) { bool pushName = MACRO_DrawEntityNames(context); if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); } DrawMeOnlyVisitor(m_associatedGenericCloud->getBB()).visit(m_root); if (pushName) glPopName(); } }
void ccGenericMesh::drawMeOnly(CC_DRAW_CONTEXT& context) { ccGenericPointCloud* vertices = getAssociatedCloud(); if (!vertices) return; handleColorRamp(context); //3D pass if (MACRO_Draw3D(context)) { //any triangle? unsigned triNum = size(); if (triNum == 0) return; //L.O.D. bool lodEnabled = (triNum > GET_MAX_LOD_FACES_NUMBER() && context.decimateMeshOnMove && MACRO_LODActivated(context)); unsigned decimStep = (lodEnabled ? (unsigned)ceil((float)triNum*3 / (float)GET_MAX_LOD_FACES_NUMBER()) : 1); unsigned displayedTriNum = triNum / decimStep; //display parameters glDrawParams glParams; getDrawingParameters(glParams); glParams.showNorms &= bool(MACRO_LightIsEnabled(context)); //vertices visibility const ccGenericPointCloud::VisibilityTableType* verticesVisibility = vertices->getTheVisibilityArray(); bool visFiltering = (verticesVisibility && verticesVisibility->isAllocated()); //wireframe ? (not compatible with LOD) bool showWired = isShownAsWire() && !lodEnabled; //per-triangle normals? bool showTriNormals = (hasTriNormals() && triNormsShown()); //fix 'showNorms' glParams.showNorms = showTriNormals || (vertices->hasNormals() && m_normalsDisplayed); //materials & textures bool applyMaterials = (hasMaterials() && materialsShown()); bool showTextures = (hasTextures() && materialsShown() && !lodEnabled); //GL name pushing bool pushName = MACRO_DrawEntityNames(context); //special case: triangle names pushing (for picking) bool pushTriangleNames = MACRO_DrawTriangleNames(context); pushName |= pushTriangleNames; if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); //minimal display for picking mode! glParams.showNorms = false; glParams.showColors = false; //glParams.showSF --> we keep it only if SF 'NaN' values are hidden showTriNormals = false; applyMaterials = false; showTextures = false; } //in the case we need to display scalar field colors ccScalarField* currentDisplayedScalarField = 0; bool greyForNanScalarValues = true; unsigned colorRampSteps = 0; ccColorScale::Shared colorScale(0); if (glParams.showSF) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); ccPointCloud* cloud = static_cast<ccPointCloud*>(vertices); greyForNanScalarValues = (cloud->getCurrentDisplayedScalarField() && cloud->getCurrentDisplayedScalarField()->areNaNValuesShownInGrey()); if (greyForNanScalarValues && pushName) { //in picking mode, no need to take SF into account if we don't hide any points! glParams.showSF = false; } else { currentDisplayedScalarField = cloud->getCurrentDisplayedScalarField(); colorScale = currentDisplayedScalarField->getColorScale(); colorRampSteps = currentDisplayedScalarField->getColorRampSteps(); assert(colorScale); //get default color ramp if cloud has no scale associated?! if (!colorScale) colorScale = ccColorScalesManager::GetUniqueInstance()->getDefaultScale(ccColorScalesManager::BGYR); } } //materials or color? bool colorMaterial = false; if (glParams.showSF || glParams.showColors) { applyMaterials = false; colorMaterial = true; glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); } //in the case we need to display vertex colors ColorsTableType* rgbColorsTable = 0; if (glParams.showColors) { if (isColorOverriden()) { glColor3ubv(m_tempColor); glParams.showColors = false; } else { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); rgbColorsTable = static_cast<ccPointCloud*>(vertices)->rgbColors(); } } else { glColor3fv(context.defaultMat.diffuseFront); } if (glParams.showNorms) { //DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version can fall to 1.0! glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); glEnable(GL_LIGHTING); context.defaultMat.applyGL(true,colorMaterial); } //in the case we need normals (i.e. lighting) NormsIndexesTableType* normalsIndexesTable = 0; ccNormalVectors* compressedNormals = 0; if (glParams.showNorms) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); normalsIndexesTable = static_cast<ccPointCloud*>(vertices)->normals(); compressedNormals = ccNormalVectors::GetUniqueInstance(); } //stipple mask if (stipplingEnabled()) EnableGLStippleMask(true); if (!pushTriangleNames && !visFiltering && !(applyMaterials || showTextures) && (!glParams.showSF || greyForNanScalarValues)) { //the GL type depends on the PointCoordinateType 'size' (float or double) GLenum GL_COORD_TYPE = sizeof(PointCoordinateType) == 4 ? GL_FLOAT : GL_DOUBLE; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_COORD_TYPE,0,GetVertexBuffer()); if (glParams.showNorms) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_COORD_TYPE,0,GetNormalsBuffer()); } if (glParams.showSF || glParams.showColors) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3,GL_UNSIGNED_BYTE,0,GetColorsBuffer()); } //we can scan and process each chunk separately in an optimized way //we mimic the way ccMesh beahves by using virtual chunks! unsigned chunks = static_cast<unsigned>(ceil((double)displayedTriNum/(double)MAX_NUMBER_OF_ELEMENTS_PER_CHUNK)); unsigned chunkStart = 0; const colorType* col = 0; for (unsigned k=0; k<chunks; ++k, chunkStart += MAX_NUMBER_OF_ELEMENTS_PER_CHUNK) { //virtual chunk size const unsigned chunkSize = k+1 < chunks ? MAX_NUMBER_OF_ELEMENTS_PER_CHUNK : (displayedTriNum % MAX_NUMBER_OF_ELEMENTS_PER_CHUNK); //vertices PointCoordinateType* _vertices = GetVertexBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_vertices,vertices->getPoint(ti->i1)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i2)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i3)->u,sizeof(PointCoordinateType)*3); _vertices+=3; } //scalar field if (glParams.showSF) { colorType* _rgbColors = GetColorsBuffer(); assert(colorScale); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); col = currentDisplayedScalarField->getValueColor(ti->i1); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i2); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i3); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; } } //colors else if (glParams.showColors) { colorType* _rgbColors = GetColorsBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_rgbColors,rgbColorsTable->getValue(ti->i1),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i2),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i3),sizeof(colorType)*3); _rgbColors += 3; } } //normals if (glParams.showNorms) { PointCoordinateType* _normals = GetNormalsBuffer(); if (showTriNormals) { for (unsigned n=0; n<chunkSize; n+=decimStep) { CCVector3 Na, Nb, Nc; getTriangleNormals(chunkStart + n, Na, Nb, Nc); memcpy(_normals,Na.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nb.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nc.u,sizeof(PointCoordinateType)*3); _normals+=3; } } else { for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_normals,vertices->getPointNormal(ti->i1).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i2).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i3).u,sizeof(PointCoordinateType)*3); _normals+=3; } } } if (!showWired) { glDrawArrays(lodEnabled ? GL_POINTS : GL_TRIANGLES,0,(chunkSize/decimStep)*3); } else { glDrawElements(GL_LINES,(chunkSize/decimStep)*6,GL_UNSIGNED_INT,GetWireVertexIndexes()); } } //disable arrays glDisableClientState(GL_VERTEX_ARRAY); if (glParams.showNorms) glDisableClientState(GL_NORMAL_ARRAY); if (glParams.showSF || glParams.showColors) glDisableClientState(GL_COLOR_ARRAY); } else { //current vertex color const colorType *col1=0,*col2=0,*col3=0; //current vertex normal const PointCoordinateType *N1=0,*N2=0,*N3=0; //current vertex texture coordinates float *Tx1=0,*Tx2=0,*Tx3=0; //loop on all triangles int lasMtlIndex = -1; if (showTextures) { //#define TEST_TEXTURED_BUNDLER_IMPORT #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(context.sourceBlend, context.destBlend); #endif glEnable(GL_TEXTURE_2D); } if (pushTriangleNames) glPushName(0); GLenum triangleDisplayType = lodEnabled ? GL_POINTS : showWired ? GL_LINE_LOOP : GL_TRIANGLES; glBegin(triangleDisplayType); //per-triangle normals const NormsIndexesTableType* triNormals = getTriNormsTable(); //materials const ccMaterialSet* materials = getMaterialSet(); for (unsigned n=0; n<triNum; ++n) { //current triangle vertices const CCLib::TriangleSummitsIndexes* tsi = getTriangleIndexes(n); //LOD: shall we display this triangle? if (n % decimStep) continue; if (visFiltering) { //we skip the triangle if at least one vertex is hidden if ((verticesVisibility->getValue(tsi->i1) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i2) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i3) != POINT_VISIBLE)) continue; } if (glParams.showSF) { assert(colorScale); col1 = currentDisplayedScalarField->getValueColor(tsi->i1); if (!col1) continue; col2 = currentDisplayedScalarField->getValueColor(tsi->i2); if (!col2) continue; col3 = currentDisplayedScalarField->getValueColor(tsi->i3); if (!col3) continue; } else if (glParams.showColors) { col1 = rgbColorsTable->getValue(tsi->i1); col2 = rgbColorsTable->getValue(tsi->i2); col3 = rgbColorsTable->getValue(tsi->i3); } if (glParams.showNorms) { if (showTriNormals) { assert(triNormals); int n1,n2,n3; getTriangleNormalIndexes(n,n1,n2,n3); N1 = (n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n1)).u : 0); N2 = (n1==n2 ? N1 : n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n2)).u : 0); N3 = (n1==n3 ? N1 : n3>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n3)).u : 0); } else { N1 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i1)).u; N2 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i2)).u; N3 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i3)).u; } } if (applyMaterials || showTextures) { assert(materials); int newMatlIndex = this->getTriangleMtlIndex(n); //do we need to change material? if (lasMtlIndex != newMatlIndex) { assert(newMatlIndex<(int)materials->size()); glEnd(); if (showTextures) { GLuint texID = (newMatlIndex>=0 ? (*materials)[newMatlIndex].texID : 0); if (texID>0) assert(glIsTexture(texID)); glBindTexture(GL_TEXTURE_2D, texID); } //if we don't have any current material, we apply default one (newMatlIndex>=0 ? (*materials)[newMatlIndex] : context.defaultMat).applyGL(glParams.showNorms,false); glBegin(triangleDisplayType); lasMtlIndex=newMatlIndex; } if (showTextures) { getTriangleTexCoordinates(n,Tx1,Tx2,Tx3); } } if (pushTriangleNames) { glEnd(); glLoadName(n); glBegin(triangleDisplayType); } else if (showWired) { glEnd(); glBegin(triangleDisplayType); } //vertex 1 if (N1) ccGL::Normal3v(N1); if (col1) glColor3ubv(col1); if (Tx1) glTexCoord2fv(Tx1); ccGL::Vertex3v(vertices->getPoint(tsi->i1)->u); //vertex 2 if (N2) ccGL::Normal3v(N2); if (col2) glColor3ubv(col2); if (Tx2) glTexCoord2fv(Tx2); ccGL::Vertex3v(vertices->getPoint(tsi->i2)->u); //vertex 3 if (N3) ccGL::Normal3v(N3); if (col3) glColor3ubv(col3); if (Tx3) glTexCoord2fv(Tx3); ccGL::Vertex3v(vertices->getPoint(tsi->i3)->u); } glEnd(); if (pushTriangleNames) glPopName(); if (showTextures) { #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPopAttrib(); //GL_COLOR_BUFFER_BIT #endif glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } } if (stipplingEnabled()) EnableGLStippleMask(false); if (colorMaterial) glDisable(GL_COLOR_MATERIAL); if (glParams.showNorms) { glDisable(GL_LIGHTING); glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); } if (pushName) glPopName(); } }
void ccSymbolCloud::drawMeOnly(CC_DRAW_CONTEXT& context) { if (!m_points->isAllocated()) return; //nothing to do?! if (!m_showSymbols && !m_showLabels) return; if (MACRO_Draw2D(context) && MACRO_Foreground(context)) { //we get display parameters glDrawParams glParams; getDrawingParameters(glParams); //standard case: list names pushing bool pushName = MACRO_DrawEntityNames(context); bool hasLabels = !m_labels.empty(); if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueID()); hasLabels = false; //no need to display labels in 'picking' mode } //we should already be in orthoprojective & centered omde //glOrtho(-halfW,halfW,-halfH,halfH,-maxS,maxS); //default color const unsigned char* color = context.pointsDefaultCol; if (isColorOverriden()) { color = m_tempColor; glParams.showColors = false; } if (!glParams.showColors) glColor3ubv(color); unsigned numberOfPoints = size(); //viewport parameters (will be used to project 3D positions to 2D) int VP[4]; context._win->getViewportArray(VP); const double* MM = context._win->getModelViewMatd(); //viewMat const double* MP = context._win->getProjectionMatd(); //projMat //only usefull when displaying labels! QFont font(context._win->getTextDisplayFont()); //takes rendering zoom into account! font.setPointSize(static_cast<int>(m_fontSize * context.renderZoom)); //font.setBold(true); QFontMetrics fontMetrics(font); double symbolSizeBackup = m_symbolSize; m_symbolSize *= static_cast<double>(context.renderZoom); double xpShift = 0.0; if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_HLEFT) xpShift = m_symbolSize/2.0; else if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_HRIGHT) xpShift = -m_symbolSize/2.0; double ypShift = 0.0; if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_VTOP) ypShift = m_symbolSize/2.0; else if (m_labelAlignFlags & ccGenericGLDisplay::ALIGN_VBOTTOM) ypShift = -m_symbolSize/2.0; //draw symbols + labels { for (unsigned i=0;i<numberOfPoints;i++) { //symbol center const CCVector3* P = getPoint(i); //project it in 2D screen coordinates GLdouble xp,yp,zp; gluProject(P->x,P->y,P->z,MM,MP,VP,&xp,&yp,&zp); //apply point color (if any) if (glParams.showColors) { color = getPointColor(i); glColor3ubv(color); } //draw associated symbol if (m_showSymbols && m_symbolSize > 0.0) { drawSymbolAt(xp-static_cast<double>(context.glW/2),yp-static_cast<double>(context.glH/2)); } //draw associated label? if (m_showLabels && hasLabels && m_labels.size() > i && !m_labels[i].isNull()) { //draw label context._win->displayText(m_labels[i],static_cast<int>(xp+xpShift),static_cast<int>(yp+ypShift),m_labelAlignFlags,0,color,&font); } } } //restore original symbol size m_symbolSize = symbolSizeBackup; if (pushName) glPopName(); } }
void cc2DLabel::drawMeOnly3D(CC_DRAW_CONTEXT& context) { assert(!m_points.empty()); //get the set of OpenGL functions (version 2.1) QOpenGLFunctions_2_1 *glFunc = context.glFunctions<QOpenGLFunctions_2_1>(); assert( glFunc != nullptr ); if ( glFunc == nullptr ) return; //standard case: list names pushing bool pushName = MACRO_DrawEntityNames(context); if (pushName) { //not particularily fast if (MACRO_DrawFastNamesOnly(context)) return; glFunc->glPushName(getUniqueIDForDisplay()); } const float c_sizeFactor = 4.0f; bool loop = false; size_t count = m_points.size(); switch (count) { case 3: { glFunc->glPushAttrib(GL_COLOR_BUFFER_BIT); glFunc->glEnable(GL_BLEND); //we draw the triangle glFunc->glColor4ub(255,255,0,128); glFunc->glBegin(GL_TRIANGLES); ccGL::Vertex3v(glFunc, m_points[0].cloud->getPoint(m_points[0].index)->u); ccGL::Vertex3v(glFunc, m_points[1].cloud->getPoint(m_points[1].index)->u); ccGL::Vertex3v(glFunc, m_points[2].cloud->getPoint(m_points[2].index)->u); glFunc->glEnd(); glFunc->glPopAttrib(); loop = true; } case 2: { //segment width glFunc->glPushAttrib(GL_LINE_BIT); glFunc->glLineWidth(c_sizeFactor * context.renderZoom); //we draw the segments if (isSelected()) ccGL::Color3v(glFunc, ccColor::red.rgba); else ccGL::Color3v(glFunc, ccColor::green.rgba); glFunc->glBegin(GL_LINES); for (unsigned i=0; i<count; i++) { if (i+1<count || loop) { ccGL::Vertex3v(glFunc, m_points[i].cloud->getPoint(m_points[i].index)->u); ccGL::Vertex3v(glFunc, m_points[(i+1)%count].cloud->getPoint(m_points[(i+1)%count].index)->u); } } glFunc->glEnd(); glFunc->glPopAttrib(); } case 1: { //display point marker as spheres { if (!c_unitPointMarker) { c_unitPointMarker = QSharedPointer<ccSphere>(new ccSphere(1.0f, 0, "PointMarker", 12)); c_unitPointMarker->showColors(true); c_unitPointMarker->setVisible(true); c_unitPointMarker->setEnabled(true); } //build-up point maker own 'context' CC_DRAW_CONTEXT markerContext = context; markerContext.drawingFlags &= (~CC_DRAW_ENTITY_NAMES); //we must remove the 'push name flag' so that the sphere doesn't push its own! markerContext.display = 0; if (isSelected() && !pushName) c_unitPointMarker->setTempColor(ccColor::red); else c_unitPointMarker->setTempColor(context.labelDefaultMarkerCol); const ccViewportParameters& viewPortParams = context.display->getViewportParameters(); ccGLCameraParameters camera; context.display->getGLCameraParameters(camera); for (unsigned i = 0; i<count; i++) { glFunc->glMatrixMode(GL_MODELVIEW); glFunc->glPushMatrix(); const CCVector3* P = m_points[i].cloud->getPoint(m_points[i].index); ccGL::Translate(glFunc, P->x, P->y, P->z); float scale = context.labelMarkerSize * m_relMarkerScale; if (viewPortParams.perspectiveView && viewPortParams.zFar > 0) { //in perspective view, the actual scale depends on the distance to the camera! const double* M = camera.modelViewMat.data(); double d = (camera.modelViewMat * CCVector3d::fromArray(P->u)).norm(); double unitD = viewPortParams.zFar / 2; //we consider that the 'standard' scale is at half the depth scale = static_cast<float>(scale * sqrt(d / unitD)); //sqrt = empirical (probably because the marker size is already partly compensated by ccGLWindow::computeActualPixelSize()) } glFunc->glScalef(scale, scale, scale); c_unitPointMarker->draw(markerContext); glFunc->glPopMatrix(); } } if (m_dispIn3D && !pushName) //no need to display label in point picking mode { QFont font(context.display->getTextDisplayFont()); //takes rendering zoom into account! //font.setPointSize(font.pointSize()+2); font.setBold(true); static const QChar ABC[3] = {'A','B','C'}; //we can't use the context 'ccGLCameraParameters' (viewport, modelView matrix, etc. ) //because it doesn't take the temporary 'GL transformation' into account! ccGLCameraParameters camera; //context.display->getGLCameraParameters(camera); glFunc->glGetIntegerv(GL_VIEWPORT, camera.viewport); glFunc->glGetDoublev(GL_PROJECTION_MATRIX, camera.projectionMat.data()); glFunc->glGetDoublev(GL_MODELVIEW_MATRIX, camera.modelViewMat.data()); //draw their name glFunc->glPushAttrib(GL_DEPTH_BUFFER_BIT); glFunc->glDisable(GL_DEPTH_TEST); for (unsigned j=0; j<count; j++) { const CCVector3* P = m_points[j].cloud->getPoint(m_points[j].index); QString title; if (count == 1) title = getName(); //for single-point labels we prefer the name else if (count == 3) title = ABC[j]; //for triangle-labels, we only display "A","B","C" else title = QString("P#%0").arg(m_points[j].index); //project it in 2D screen coordinates CCVector3d Q2D; camera.project(*P, Q2D); context.display->displayText( title, static_cast<int>(Q2D.x) + context.labelMarkerTextShift_pix, static_cast<int>(Q2D.y) + context.labelMarkerTextShift_pix, ccGenericGLDisplay::ALIGN_DEFAULT, context.labelOpacity / 100.0f, ccColor::white.rgba, &font ); } glFunc->glPopAttrib(); } } } if (pushName) { glFunc->glPopName(); } }
void cc2DLabel::drawMeOnly3D(CC_DRAW_CONTEXT& context) { assert(!m_points.empty()); //standard case: list names pushing bool pushName = MACRO_DrawEntityNames(context); if (pushName) { //not particularily fast if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); } const float c_sizeFactor = 4.0f; bool loop = false; size_t count = m_points.size(); switch (count) { case 3: { glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); //we draw the triangle glColor4ub(255,255,0,128); glBegin(GL_TRIANGLES); ccGL::Vertex3v(m_points[0].cloud->getPoint(m_points[0].index)->u); ccGL::Vertex3v(m_points[1].cloud->getPoint(m_points[1].index)->u); ccGL::Vertex3v(m_points[2].cloud->getPoint(m_points[2].index)->u); glEnd(); glPopAttrib(); loop = true; } case 2: { //segment width glPushAttrib(GL_LINE_BIT); glLineWidth(c_sizeFactor * context.renderZoom); //we draw the segments if (isSelected()) ccGL::Color3v(ccColor::red.rgba); else ccGL::Color3v(ccColor::green.rgba); glBegin(GL_LINES); for (unsigned i=0; i<count; i++) { if (i+1<count || loop) { ccGL::Vertex3v(m_points[i].cloud->getPoint(m_points[i].index)->u); ccGL::Vertex3v(m_points[(i+1)%count].cloud->getPoint(m_points[(i+1)%count].index)->u); } } glEnd(); glPopAttrib(); } case 1: { //display point marker as spheres { if (!c_unitPointMarker) { c_unitPointMarker = QSharedPointer<ccSphere>(new ccSphere(1.0f,0,"PointMarker",12)); c_unitPointMarker->showColors(true); c_unitPointMarker->setVisible(true); c_unitPointMarker->setEnabled(true); } //build-up point maker own 'context' CC_DRAW_CONTEXT markerContext = context; markerContext.flags &= (~CC_DRAW_ENTITY_NAMES); //we must remove the 'push name flag' so that the sphere doesn't push its own! markerContext._win = 0; if (isSelected() && !pushName) c_unitPointMarker->setTempColor(ccColor::red); else c_unitPointMarker->setTempColor(context.labelDefaultMarkerCol); for (unsigned i=0; i<count; i++) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); const CCVector3* P = m_points[i].cloud->getPoint(m_points[i].index); ccGL::Translate(P->x,P->y,P->z); glScalef(context.labelMarkerSize,context.labelMarkerSize,context.labelMarkerSize); c_unitPointMarker->draw(markerContext); glPopMatrix(); } } if (m_dispIn3D && !pushName) //no need to display label in point picking mode { QFont font(context._win->getTextDisplayFont()); //takes rendering zoom into account! //font.setPointSize(font.pointSize()+2); font.setBold(true); static const QChar ABC[3] = {'A','B','C'}; int VP[4]; context._win->getViewportArray(VP); const double* MM = context._win->getModelViewMatd(); //viewMat const double* MP = context._win->getProjectionMatd(); //projMat //draw their name glPushAttrib(GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); for (unsigned j=0; j<count; j++) { const CCVector3* P = m_points[j].cloud->getPoint(m_points[j].index); QString title; if (count == 1) title = getName(); //for single-point labels we prefer the name else if (count == 3) title = ABC[j]; //for triangle-labels, we only display "A","B","C" else title = QString("P#%0").arg(m_points[j].index); //project it in 2D screen coordinates GLdouble xp,yp,zp; gluProject(P->x,P->y,P->z,MM,MP,VP,&xp,&yp,&zp); context._win->displayText( title, static_cast<int>(xp) + context.labelMarkerTextShift_pix, static_cast<int>(yp) + context.labelMarkerTextShift_pix, ccGenericGLDisplay::ALIGN_DEFAULT, context.labelOpacity/100.0f, ccColor::white.rgba, &font ); } glPopAttrib(); } } } if (pushName) glPopName(); }
void ccGBLSensor::drawMeOnly(CC_DRAW_CONTEXT& context) { //we draw here a little 3d representation of the sensor if (MACRO_Draw3D(context)) { bool pushName = MACRO_DrawEntityNames(context); if (pushName) { //not particulary fast if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); } //DGM FIXME: this display routine is crap! //apply rigid transformation glMatrixMode(GL_MODELVIEW); glPushMatrix(); { ccIndexedTransformation sensorPos; if (!getAbsoluteTransformation(sensorPos,m_activeIndex)) { //no visible position for this index! glPopMatrix(); if (pushName) glPopName(); return; } glMultMatrixf(sensorPos.data()); } //test: center as sphere /*{ ccSphere sphere(m_scale/10,0,"Center",12); sphere.showColors(true); sphere.setVisible(true); sphere.setEnabled(true); CC_DRAW_CONTEXT sphereContext = context; sphereContext.flags &= (~CC_DRAW_ENTITY_NAMES); //we must remove the 'push name flag' so that the sphere doesn't push its own! sphereContext._win = 0; sphere.setTempColor(ccColor::magenta); sphere.draw(sphereContext); } //*/ const PointCoordinateType halfHeadSize = static_cast<PointCoordinateType>(0.3); //sensor axes { //increased width glPushAttrib(GL_LINE_BIT); GLfloat width; glGetFloatv(GL_LINE_WIDTH,&width); glLineWidth(width+1); PointCoordinateType axisLength = halfHeadSize * m_scale; ccGL::Color3v(ccColor::red.rgba); CCVector3 C(0,0,0); glBegin(GL_LINES); ccGL::Vertex3v(C.u); ccGL::Vertex3(C.x+axisLength,C.y,C.z); glEnd(); ccGL::Color3v(ccColor::green.rgba); glBegin(GL_LINES); ccGL::Vertex3v(C.u); ccGL::Vertex3(C.x,C.y+axisLength,C.z); glEnd(); ccGL::Color3v(ccColor::blue.rgba); glBegin(GL_LINES); ccGL::Vertex3v(C.u); ccGL::Vertex3(C.x,C.y,C.z+axisLength); glEnd(); glPopAttrib(); } //sensor head { CCVector3 minCorner(-halfHeadSize,-halfHeadSize,-halfHeadSize); CCVector3 maxCorner( halfHeadSize, halfHeadSize, halfHeadSize); minCorner *= m_scale; maxCorner *= m_scale; ccBBox bbHead(minCorner,maxCorner); bbHead.draw(m_color); } //sensor legs { CCVector3 headConnect = /*headCenter*/ - CCVector3(0,0,static_cast<PointCoordinateType>(halfHeadSize)*m_scale); ccGL::Color3v(m_color.rgb); glBegin(GL_LINES); ccGL::Vertex3v(headConnect.u); ccGL::Vertex3(-m_scale,-m_scale,-m_scale); ccGL::Vertex3v(headConnect.u); ccGL::Vertex3(-m_scale,m_scale,-m_scale); ccGL::Vertex3v(headConnect.u); ccGL::Vertex3(m_scale,0,-m_scale); glEnd(); } if (pushName) glPopName(); glPopMatrix(); } }
void cc2DLabel::drawMeOnly3D(CC_DRAW_CONTEXT& context) { assert(!m_points.empty()); //standard case: list names pushing bool pushName = MACRO_DrawEntityNames(context); if (pushName) { //not particularily fast if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); } const float c_sizeFactor = 4.0f; bool loop=false; size_t count = m_points.size(); switch (count) { case 3: { glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); //we draw the triangle glColor4ub(255,255,0,128); glBegin(GL_TRIANGLES); for (unsigned i=0; i<count; ++i) ccGL::Vertex3v(m_points[i].cloud->getPoint(m_points[i].index)->u); glEnd(); glPopAttrib(); loop=true; } case 2: { //segment width glPushAttrib(GL_LINE_BIT); glLineWidth(c_sizeFactor); //we draw the segments if (isSelected()) glColor3ubv(ccColor::red); else glColor3ubv(ccColor::green); glBegin(GL_LINES); for (unsigned i=0; i<count; i++) { if (i+1<count || loop) { ccGL::Vertex3v(m_points[i].cloud->getPoint(m_points[i].index)->u); ccGL::Vertex3v(m_points[(i+1)%count].cloud->getPoint(m_points[(i+1)%count].index)->u); } } glEnd(); glPopAttrib(); } case 1: { //display point marker as spheres { if (!c_unitPointMarker) { c_unitPointMarker = QSharedPointer<ccSphere>(new ccSphere(1.0f,0,"PointMarker",12)); c_unitPointMarker->showColors(true); c_unitPointMarker->setVisible(true); c_unitPointMarker->setEnabled(true); } //build-up point maker own 'context' CC_DRAW_CONTEXT markerContext = context; markerContext.flags &= (~CC_DRAW_ENTITY_NAMES); //we must remove the 'push name flag' so that the sphere doesn't push its own! markerContext._win = 0; if (isSelected() && !pushName) c_unitPointMarker->setTempColor(ccColor::red); else c_unitPointMarker->setTempColor(ccColor::magenta); for (unsigned i=0; i<count; i++) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); const CCVector3* P = m_points[i].cloud->getPoint(m_points[i].index); ccGL::Translate(P->x,P->y,P->z); glScalef(context.pickedPointsRadius,context.pickedPointsRadius,context.pickedPointsRadius); c_unitPointMarker->draw(markerContext); glPopMatrix(); } } if (m_dispIn3D && !pushName) //no need to display label in point picking mode { QFont font(context._win->getTextDisplayFont()); //takes rendering zoom into account! //font.setPointSize(font.pointSize()+2); font.setBold(true); //draw their name glPushAttrib(GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); for (unsigned j=0; j<count; j++) { const CCVector3* P = m_points[j].cloud->getPoint(m_points[j].index); QString title = (count == 1 ? getName() : QString("P#%0").arg(m_points[j].index)); context._win->display3DLabel( title, *P+CCVector3(context.pickedPointsTextShift), ccColor::magenta, font); } glPopAttrib(); } } } if (pushName) glPopName(); }
void ccSample::drawMeOnly(CC_DRAW_CONTEXT& context) { if (MACRO_Draw3D(context)) { if (!this->getSample()) return; QOpenGLFunctions_2_1* glFunc = context.glFunctions<QOpenGLFunctions_2_1>(); assert(glFunc != nullptr); bool pushName = MACRO_DrawEntityNames(context); if (pushName) { // not particularily fast if (MACRO_DrawFastNamesOnly(context)) return; glFunc->glPushName(getUniqueIDForDisplay()); } if (!c_unitPointMarker) { c_unitPointMarker = QSharedPointer<ccSphere>(new ccSphere(m_radius_, 0, "PointMarker", 12)); c_unitPointMarker->showColors(true); c_unitPointMarker->setVisible(true); c_unitPointMarker->setEnabled(true); } // build-up point maker own 'context' CC_DRAW_CONTEXT markerContext = context; markerContext.drawingFlags &= (~CC_DRAW_ENTITY_NAMES); // we must remove the 'push name flag' so // that the sphere doesn't push its own! markerContext.display = nullptr; if (isSelected() && !pushName) { c_unitPointMarker->setTempColor(ccColor::red); c_unitPointMarker->setRadius(2 * m_radius_); } else { c_unitPointMarker->setTempColor(ccColor::magenta); c_unitPointMarker->setRadius(m_radius_); } glFunc->glMatrixMode(GL_MODELVIEW); glFunc->glPushMatrix(); float x, y, z; Eigen::Vector3f p = this->getSample()->getPosition(); // const CCVector3* P = m_points[i].cloud->getPoint(m_points[i].index); // ccGL::Translate(); glFunc->glTranslatef(p(0), p(1), p(2)); glFunc->glScalef(context.labelMarkerSize, context.labelMarkerSize, context.labelMarkerSize); m_current_scaling_ = context.labelMarkerSize; c_unitPointMarker->draw(markerContext); glFunc->glPopMatrix(); drawStratPos(context); if (pushName) glFunc->glPopName(); } }