void ccIndexedTransformationBuffer::drawMeOnly(CC_DRAW_CONTEXT& context) { //no picking enabled on trans. buffers if (MACRO_DrawNames(context)) return; //only in 3D if (!MACRO_Draw3D(context)) return; size_t count = size(); //show path { glColor3ubv(ccColor::green); glBegin(count > 1 && m_showAsPolyline ? GL_LINE_STRIP : GL_POINTS); //show path as a polyline or points? for (ccIndexedTransformationBuffer::const_iterator it=begin(); it!=end(); ++it) glVertex3fv(it->getTranslation()); glEnd(); } //show trihedrons? if (m_showTrihedrons) { for (ccIndexedTransformationBuffer::const_iterator it=begin(); it!=end(); ++it) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(it->data()); glBegin(GL_LINES); glColor3f(1.0f,0.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(m_trihedronsScale,0.0f,0.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.0f,m_trihedronsScale,0.0f); glColor3f(0.0f,0.7f,1.0f); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.0f,0.0f,m_trihedronsScale); glEnd(); glPopMatrix(); } } }
void ccHObject::draw(CC_DRAW_CONTEXT& context) { if (!isEnabled()) return; //are we currently drawing objects in 2D or 3D? bool draw3D = MACRO_Draw3D(context); //the entity must be either visible and selected, and of course it should be displayed in this context bool drawInThisContext = ((m_visible || m_selected) && m_currentDisplay == context._win); //no need to display anything but clouds and meshes in "element picking mode" drawInThisContext &= ( ( !MACRO_DrawPointNames(context) || isKindOf(CC_TYPES::POINT_CLOUD) ) || ( !MACRO_DrawTriangleNames(context) || isKindOf(CC_TYPES::MESH) )); //apply 3D 'temporary' transformation (for display only) if (draw3D && m_glTransEnabled) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(m_glTrans.data()); } //draw entity if (m_visible && drawInThisContext) { if (( !m_selected || !MACRO_SkipSelected(context) ) && ( m_selected || !MACRO_SkipUnselected(context) )) { //apply default color (in case of) glColor3ubv(context.pointsDefaultCol); drawMeOnly(context); //draw name in 3D (we display it in the 2D foreground layer in fact!) if (m_showNameIn3D && MACRO_Draw2D(context) && MACRO_Foreground(context) && !MACRO_DrawNames(context)) drawNameIn3D(context); } } //draw entity's children for (Container::iterator it = m_children.begin(); it != m_children.end(); ++it) (*it)->draw(context); //if the entity is currently selected, we draw its bounding-box if (m_selected && draw3D && drawInThisContext && !MACRO_DrawNames(context)) { switch (m_selectionBehavior) { case SELECTION_AA_BBOX: drawBB(context.bbDefaultCol); break; case SELECTION_FIT_BBOX: { ccGLMatrix trans; ccBBox box = getFitBB(trans); if (box.isValid()) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(trans.data()); box.draw(context.bbDefaultCol); glPopMatrix(); } } break; case SELECTION_IGNORED: break; default: assert(false); } } if (draw3D && m_glTransEnabled) glPopMatrix(); }
void cc2DLabel::drawMeOnly2D(CC_DRAW_CONTEXT& context) { if (!m_dispIn2D) return; assert(!m_points.empty()); //standard case: list names pushing bool pushName = MACRO_DrawNames(context); if (pushName) glPushName(getUniqueID()); //we should already be in orthoprojective & centered omde //glOrtho(-halfW,halfW,-halfH,halfH,-maxS,maxS); int strHeight = 0; int titleHeight = 0; QString title(getName()); QStringList body; GLdouble arrowDestX=-1.0,arrowDestY=-1.0; QFont bodyFont,titleFont; if (!pushName) { /*** line from 2D point to label ***/ //compute arrow head position CCVector3 arrowDest; m_points[0].cloud->getPoint(m_points[0].index,arrowDest); for (unsigned i=1;i<m_points.size();++i) arrowDest += *m_points[i].cloud->getPointPersistentPtr(m_points[i].index); arrowDest /= (PointCoordinateType)m_points.size(); //project it in 2D screen coordinates int VP[4]; context._win->getViewportArray(VP); const double* MM = context._win->getModelViewMatd(); //viewMat const double* MP = context._win->getProjectionMatd(); //projMat GLdouble zp; gluProject(arrowDest.x,arrowDest.y,arrowDest.z,MM,MP,VP,&arrowDestX,&arrowDestY,&zp); /*** label border ***/ bodyFont = context._win->getTextDisplayFont(); titleFont = QFont(context._win->getTextDisplayFont()); titleFont.setBold(true); QFontMetrics titleFontMetrics(titleFont); QFontMetrics bodyFontMetrics(bodyFont); strHeight = bodyFontMetrics.height(); titleHeight = titleFontMetrics.height(); if (m_showFullBody) body = getLabelContent(context.dispNumberPrecision); //base box dimension int dx = 150; dx = std::max(dx,titleFontMetrics.width(title)); int dy = c_margin; //top vertical margin dy += titleHeight; //title if (!body.empty()) { dy += c_margin; //vertical margin above separator for (int j=0;j<body.size();++j) { dx = std::max(dx,bodyFontMetrics.width(body[j])); dy += (c_margin+strHeight); //margin + body line height } } else { dy += c_margin; // vertical margin (purely for aesthetics) } dy += c_margin; // bottom vertical margin dx += c_margin*2; // horizontal margins //main rectangle m_labelROI[0]=0; m_labelROI[1]=0; m_labelROI[2]=dx; m_labelROI[3]=dy; //close button /*m_closeButtonROI[2]=dx-c_margin; m_closeButtonROI[0]=m_closeButtonROI[2]-c_buttonSize; m_closeButtonROI[3]=c_margin; m_closeButtonROI[1]=m_closeButtonROI[3]+c_buttonSize; //*/ //automatically elide the title //title = titleFontMetrics.elidedText(title,Qt::ElideRight,m_closeButtonROI[0]-2*c_margin); } int halfW = (context.glW>>1); int halfH = (context.glH>>1); //draw label rectangle int xStart = m_lastScreenPos[0] = (int)((float)context.glW * m_screenPos[0]); int yStart = m_lastScreenPos[1] = (int)((float)context.glH * (1.0f-m_screenPos[1])); //colors bool highlighted = (!pushName && isSelected()); //default background color colorType defaultBkgColor[4]; memcpy(defaultBkgColor,context.labelDefaultCol,sizeof(colorType)*3); defaultBkgColor[3]=(colorType)((float)context.labelsTransparency*(float)MAX_COLOR_COMP/100.0f); //default border color (mustn't be totally transparent!) colorType defaultBorderColor[4]; if (highlighted) memcpy(defaultBorderColor,ccColor::red,sizeof(colorType)*3); else memcpy(defaultBorderColor,context.labelDefaultCol,sizeof(colorType)*3); defaultBorderColor[3]=(colorType)((float)(50+context.labelsTransparency/2)*(float)MAX_COLOR_COMP/100.0f); glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(-halfW+xStart,-halfH+yStart,0); if (!pushName) { //compute arrow base position relatively to the label rectangle (for 0 to 8) int arrowBaseConfig = 0; int iArrowDestX = (int)arrowDestX-xStart; int iArrowDestY = (int)arrowDestY-yStart; { if (iArrowDestX < m_labelROI[0]) //left arrowBaseConfig += 0; else if (iArrowDestX > m_labelROI[2]) //Right arrowBaseConfig += 2; else //Middle arrowBaseConfig += 1; if (iArrowDestY > -m_labelROI[1]) //Top arrowBaseConfig += 0; else if (iArrowDestY < -m_labelROI[3]) //Bottom arrowBaseConfig += 6; else //Middle arrowBaseConfig += 3; } //we make the arrow base start from the nearest corner if (arrowBaseConfig != 4) //4 = label above point! { glColor4ubv(defaultBorderColor); glBegin(GL_TRIANGLE_FAN); glVertex2d(arrowDestX-xStart,arrowDestY-yStart); switch(arrowBaseConfig) { case 0: //top-left corner glVertex2i(m_labelROI[0], -m_labelROI[1]-2*c_arrowBaseSize); glVertex2i(m_labelROI[0], -m_labelROI[1]); glVertex2i(m_labelROI[0]+2*c_arrowBaseSize, -m_labelROI[1]); break; case 1: //top-middle edge glVertex2i(std::max(m_labelROI[0],iArrowDestX-c_arrowBaseSize), -m_labelROI[1]); glVertex2i(std::min(m_labelROI[2],iArrowDestX+c_arrowBaseSize), -m_labelROI[1]); break; case 2: //top-right corner glVertex2i(m_labelROI[2], -m_labelROI[1]-2*c_arrowBaseSize); glVertex2i(m_labelROI[2], -m_labelROI[1]); glVertex2i(m_labelROI[2]-2*c_arrowBaseSize, -m_labelROI[1]); break; case 3: //middle-left edge glVertex2i(m_labelROI[0], std::min(-m_labelROI[1],iArrowDestY+c_arrowBaseSize)); glVertex2i(m_labelROI[0], std::max(-m_labelROI[3],iArrowDestY-c_arrowBaseSize)); break; case 4: //middle of rectangle! break; case 5: //middle-right edge glVertex2i(m_labelROI[2], std::min(-m_labelROI[1],iArrowDestY+c_arrowBaseSize)); glVertex2i(m_labelROI[2], std::max(-m_labelROI[3],iArrowDestY-c_arrowBaseSize)); break; case 6: //bottom-left corner glVertex2i(m_labelROI[0], -m_labelROI[3]+2*c_arrowBaseSize); glVertex2i(m_labelROI[0], -m_labelROI[3]); glVertex2i(m_labelROI[0]+2*c_arrowBaseSize, -m_labelROI[3]); break; case 7: //bottom-middle edge glVertex2i(std::max(m_labelROI[0],iArrowDestX-c_arrowBaseSize), -m_labelROI[3]); glVertex2i(std::min(m_labelROI[2],iArrowDestX+c_arrowBaseSize), -m_labelROI[3]); break; case 8: //bottom-right corner glVertex2i(m_labelROI[2], -m_labelROI[3]+2*c_arrowBaseSize); glVertex2i(m_labelROI[2], -m_labelROI[3]); glVertex2i(m_labelROI[2]-2*c_arrowBaseSize, -m_labelROI[3]); break; } glEnd(); } } //main rectangle glColor4ubv(defaultBkgColor); glBegin(GL_QUADS); glVertex2i(m_labelROI[0], -m_labelROI[1]); glVertex2i(m_labelROI[0], -m_labelROI[3]); glVertex2i(m_labelROI[2], -m_labelROI[3]); glVertex2i(m_labelROI[2], -m_labelROI[1]); glEnd(); //if (highlighted) { glPushAttrib(GL_LINE_BIT); glLineWidth(3.0f); glColor4ubv(defaultBorderColor); glBegin(GL_LINE_LOOP); glVertex2i(m_labelROI[0], -m_labelROI[1]); glVertex2i(m_labelROI[0], -m_labelROI[3]); glVertex2i(m_labelROI[2], -m_labelROI[3]); glVertex2i(m_labelROI[2], -m_labelROI[1]); glEnd(); glPopAttrib(); } //draw close button /*glColor3ubv(ccColor::black); glBegin(GL_LINE_LOOP); glVertex2i(m_closeButtonROI[0],-m_closeButtonROI[1]); glVertex2i(m_closeButtonROI[0],-m_closeButtonROI[3]); glVertex2i(m_closeButtonROI[2],-m_closeButtonROI[3]); glVertex2i(m_closeButtonROI[2],-m_closeButtonROI[1]); glEnd(); glBegin(GL_LINES); glVertex2i(m_closeButtonROI[0]+2,-m_closeButtonROI[1]+2); glVertex2i(m_closeButtonROI[2]-2,-m_closeButtonROI[3]-2); glVertex2i(m_closeButtonROI[2]-2,-m_closeButtonROI[1]+2); glVertex2i(m_closeButtonROI[0]+2,-m_closeButtonROI[3]-2); glEnd(); //*/ //display text if (!pushName) { int xStartRel = c_margin; int yStartRel = -c_margin; yStartRel -= titleHeight; const colorType* defaultTextColor = (context.labelsTransparency<40 ? context.textDefaultCol : ccColor::darkBlue); context._win->displayText(title,xStart+xStartRel,yStart+yStartRel,ccGenericGLDisplay::ALIGN_DEFAULT,0,defaultTextColor,&titleFont); yStartRel -= c_margin; if (!body.empty()) { //line separation glColor4ubv(defaultBorderColor); glBegin(GL_LINES); glVertex2i(xStartRel,yStartRel); glVertex2i(xStartRel+m_labelROI[2]-m_labelROI[0]-2*c_margin,yStartRel); glEnd(); //display body yStartRel -= c_margin; for (int i=0;i<body.size();++i) { yStartRel -= strHeight; context._win->displayText(body[i],xStart+xStartRel,yStart+yStartRel,ccGenericGLDisplay::ALIGN_DEFAULT,0,defaultTextColor,&bodyFont); } } } glPopAttrib(); glPopMatrix(); if (pushName) glPopName(); }
void cc2DLabel::drawMeOnly3D(CC_DRAW_CONTEXT& context) { assert(!m_points.empty()); //standard case: list names pushing bool pushName = MACRO_DrawNames(context); if (pushName) glPushName(getUniqueID()); const float c_sizeFactor = 4.0f; bool loop=false; unsigned 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) glVertex3fv(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) { glVertex3fv(m_points[i].cloud->getPoint(m_points[i].index)->u); glVertex3fv(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' bool pushName = MACRO_DrawNames(context); CC_DRAW_CONTEXT markerContext = context; markerContext.flags &= (~CC_DRAW_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->setColor(ccColor::red); else c_unitPointMarker->setColor(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); glTranslatef(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()); //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 ccHObject::draw(CC_DRAW_CONTEXT& context) { if (!isEnabled()) return; bool draw3D = MACRO_Draw3D(context); bool drawInThisContext = (!m_visible && !m_selected ? false : m_currentDisplay == context._win); //no need to display anything but clouds and meshes in "point picking mode" bool DrawMesh = false; if (MACRO_DrawTriangleNames(context) && isKindOf(CC_MESH)) { ccGenericMesh *mesh = static_cast<ccGenericMesh*>(this); ccGenericPointCloud *cloud = mesh->getAssociatedCloud(); DrawMesh = (cloud == NULL || !cloud->isEnabled()); } drawInThisContext &= ( (!MACRO_DrawPointNames(context) || isKindOf(CC_POINT_CLOUD)) || (!MACRO_DrawTriangleNames(context) || DrawMesh) ); //apply 3D 'temporary' transformation (for display only) if (draw3D && m_glTransEnabled) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(m_glTrans.data()); } //draw entity if (m_visible && drawInThisContext) { if ((!m_selected || !MACRO_SkipSelected(context)) && (m_selected || !MACRO_SkipUnselected(context))) { glColor3ubv(context.pointsDefaultCol); drawMeOnly(context); //draw name in 3D (we display it in the 2D foreground layer in fact!) if (m_showNameIn3D && MACRO_Draw2D(context) && MACRO_Foreground(context) && !MACRO_DrawNames(context)) drawNameIn3D(context); } } //draw entity's children for (Container::iterator it = m_children.begin(); it!=m_children.end(); ++it) (*it)->draw(context); //if the entity is currently selected if (m_selected && draw3D && drawInThisContext) { switch (m_selectionBehavior) { case SELECTION_AA_BBOX: drawBB(context.bbDefaultCol); break; case SELECTION_FIT_BBOX: { ccGLMatrix trans; ccBBox box = getFitBB(trans); if (box.isValid()) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(trans.data()); box.draw(context.bbDefaultCol); glPopMatrix(); } } break; case SELECTION_IGNORED: break; default: assert(false); } } if (draw3D && m_glTransEnabled) glPopMatrix(); }
//================================================draw====================================================// void ccHObject::draw(CC_DRAW_CONTEXT& context) { if (!isEnabled())return; //是否开启 //are we currently drawing objects in 2D or 3D? bool draw3D = MACRO_Draw3D(context); //判断是在三维上绘制还是在二维上绘制? //the entity must be either visible and selected, and of course it should be displayed in this context //是否可视,是否被选择,是否在当前窗口下显示 bool drawInThisContext = ((m_visible || m_selected) && m_currentDisplay == context._win); //no need to display anything but clouds and meshes in "element picking mode" drawInThisContext &= ( ( !MACRO_DrawPointNames(context) || isKindOf(CC_TYPES::POINT_CLOUD) ) || ( !MACRO_DrawTriangleNames(context) || isKindOf(CC_TYPES::MESH) )); if (draw3D){ //apply 3D 'temporary' transformation (for display only) if (m_glTransEnabled){ //可以进行变换 glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(m_glTrans.data()); } if ( context.decimateCloudOnMove //LOD for clouds is enabled? && context.currentLODLevel >= context.minLODLevel //and we are currently rendering higher levels? ){ //only for real clouds drawInThisContext &= isA(CC_TYPES::POINT_CLOUD); //LOD只对点云有效?????????? } } //draw entity if (m_visible && drawInThisContext){ if (( !m_selected || !MACRO_SkipSelected(context) ) && ( m_selected || !MACRO_SkipUnselected(context) )) { //apply default color (in case of) ccGL::Color3v(context.pointsDefaultCol.rgb); //不同的物体绘制方式不同 drawMeOnly(context); //draw name in 3D (we display it in the 2D foreground layer in fact!) if (m_showNameIn3D && MACRO_Draw2D(context) && MACRO_Foreground(context) && !MACRO_DrawNames(context)) drawNameIn3D(context); } } //draw entity's children //绘制物体的子物体 for (Container::iterator it = m_children.begin(); it != m_children.end(); ++it) (*it)->draw(context); //绘制BB //if the entity is currently selected, we draw its bounding-box if (m_selected && draw3D && drawInThisContext && !MACRO_DrawNames(context) && context.currentLODLevel == 0){ drawBB(context.bbDefaultCol); } if (draw3D && m_glTransEnabled) glPopMatrix(); }