From cba94b2660b4505a655cd0225c546bcd24ef8253 Mon Sep 17 00:00:00 2001 From: mrlukeparry Date: Tue, 17 Jul 2012 12:40:22 +0200 Subject: [PATCH] Sketcher: improve symmetric constraint visual --- src/Mod/Sketcher/Gui/SoDatumLabel.cpp | 251 +++++++++++++++----- src/Mod/Sketcher/Gui/SoDatumLabel.h | 6 +- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 50 ++-- 3 files changed, 206 insertions(+), 101 deletions(-) diff --git a/src/Mod/Sketcher/Gui/SoDatumLabel.cpp b/src/Mod/Sketcher/Gui/SoDatumLabel.cpp index 7b7cb544b..36b8ed6a2 100644 --- a/src/Mod/Sketcher/Gui/SoDatumLabel.cpp +++ b/src/Mod/Sketcher/Gui/SoDatumLabel.cpp @@ -326,6 +326,62 @@ void SoDatumLabel::generatePrimitives(SoAction * action) pv.setPoint( img4 ); shapeVertex(&pv); + this->endShape(); + } else if (this->datumtype.getValue() == SYMMETRIC) { + + // Get the Scale + SoState *state = action->getState(); + const SbViewVolume & vv = SoViewVolumeElement::get(state); + float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.4f); + + SbVec3f dir = (p2-p1); + dir.normalize(); + SbVec3f norm (-dir[1],dir[0],0); + + float margin = 0.01f; + margin *= scale; + + // Calculate coordinates for the first arrow + SbVec3f ar0, ar1, ar2; + ar0 = p1 + dir * 5 * margin; + ar1 = ar0 - dir * 0.866 * 2 * margin; // Base Point of Arrow + ar2 = ar1 + norm * margin; // Triangular corners + ar1 -= norm * margin; + + // Calculate coordinates for the second arrow + SbVec3f ar3, ar4, ar5; + ar3 = p2 - dir * 5 * margin; + ar4 = ar3 + dir * 0.866 * 2 * margin; // Base Point of 2nd Arrow + + ar5 = ar4 + norm * margin; // Triangular corners + ar4 -= norm * margin; + + SoPrimitiveVertex pv; + + this->beginShape(action, TRIANGLES); + + pv.setNormal( SbVec3f(0.f, 0.f, 1.f) ); + + // Set coordinates + pv.setPoint( ar0 ); + shapeVertex(&pv); + + pv.setPoint( ar1 ); + shapeVertex(&pv); + + pv.setPoint( ar2 ); + shapeVertex(&pv); + + // Set coordinates + pv.setPoint( ar3 ); + shapeVertex(&pv); + + pv.setPoint( ar4 ); + shapeVertex(&pv); + + pv.setPoint( ar5 ); + shapeVertex(&pv); + this->endShape(); } @@ -338,26 +394,33 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action) return; if (action->handleTransparency(true)) return; - drawImage(); - SbVec2s size; - int nc; - const unsigned char * dataptr = this->image.getValue(size, nc); - if (dataptr == NULL) return; // no image - - int srcw = size[0]; - int srch = size[1]; - - // Create the quad to hold texture + // Get the Scale const SbViewVolume & vv = SoViewVolumeElement::get(state); float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.4f); - float aspectRatio = (float) srcw / (float) srch; - this->imgHeight = scale / (float) srch; - this->imgWidth = aspectRatio * (float) this->imgHeight; + const SbString* s = string.getValues(0); + bool hasText = (s->getLength() > 0) ? true : false; + SbVec2s size; + int nc; + int srcw, srch; - // Get the points stored + if(hasText) { + drawImage(); + + const unsigned char * dataptr = this->image.getValue(size, nc); + if (dataptr == NULL) return; // no image + + srcw = size[0]; + srch = size[1]; + + float aspectRatio = (float) srcw / (float) srch; + this->imgHeight = scale / (float) srch; + this->imgWidth = aspectRatio * (float) this->imgHeight; + } + + // Get the points stored in the pnt field const SbVec3f *pnts = this->pnts.getValues(0); state->push(); @@ -378,6 +441,14 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action) float offsetX, offsetY, angle; SbVec3f textOffset; + + // Get the colour + const SbColor& t = textColor.getValue(); + + // Set GL Properties + glLineWidth(2.f); + glColor3f(t[0], t[1], t[2]); + if(this->datumtype.getValue() == DISTANCE || this->datumtype.getValue() == DISTANCEX || this->datumtype.getValue() == DISTANCEY ) { float length = this->param1.getValue(); @@ -538,13 +609,6 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action) textOffset = pos; - // Get the colour - const SbColor& t = textColor.getValue(); - - // Set GL Properties - glLineWidth(this->lineWidth.getValue()); - glColor3f(t[0], t[1], t[2]); - float margin = 0.01f; margin *= scale; @@ -628,13 +692,6 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action) float margin = 0.01f; margin *= scale; - // Get the colour - const SbColor& t = textColor.getValue(); - - // Set GL Properties - glLineWidth(this->lineWidth.getValue()); - glColor3f(t[0], t[1], t[2]); - // Draw glBegin(GL_LINE_STRIP); @@ -706,59 +763,123 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action) } //Store the bounding box this->bbox.setBounds(SbVec3f(minX, minY, 0.f), SbVec3f (maxX, maxY, 0.f)); + } else if (this->datumtype.getValue() == SYMMETRIC) { + SbVec3f p1 = pnts[0]; + SbVec3f p2 = pnts[1]; + + SbVec3f dir = (p2-p1); + dir.normalize(); + SbVec3f norm (-dir[1],dir[0],0); + + float margin = 0.01f; + margin *= scale; + + // Calculate coordinates for the first arrow + SbVec3f ar0, ar1, ar2; + ar0 = p1 + dir * 4 * margin; // Tip of Arrow + ar1 = ar0 - dir * 0.866 * 2 * margin; + ar2 = ar1 + norm * margin; + ar1 -= norm * margin; + + glBegin(GL_LINES); + glVertex2f(p1[0],p1[1]); + glVertex2f(ar0[0],ar0[1]); + glVertex2f(ar0[0],ar0[1]); + glVertex2f(ar1[0],ar1[1]); + glVertex2f(ar0[0],ar0[1]); + glVertex2f(ar2[0],ar2[1]); + glEnd(); + + // Calculate coordinates for the second arrow + SbVec3f ar3, ar4, ar5; + ar3 = p2 - dir * 4 * margin; // Tip of 2nd Arrow + ar4 = ar3 + dir * 0.866 * 2 * margin; + ar5 = ar4 + norm * margin; + ar4 -= norm * margin; + + glBegin(GL_LINES); + glVertex2f(p2[0],p2[1]); + glVertex2f(ar3[0],ar3[1]); + glVertex2f(ar3[0], ar3[1]); + glVertex2f(ar4[0], ar4[1]); + glVertex2f(ar3[0], ar3[1]); + glVertex2f(ar5[0], ar5[1]); + glEnd(); + + // BOUNDING BOX CALCULATION - IMPORTANT + // Finds the mins and maxes + std::vector corners; + corners.push_back(p1); + corners.push_back(p2); + + float minX = p1[0], minY = p1[1], maxX = p1[0] , maxY = p1[1]; + for (std::vector::iterator it=corners.begin(); it != corners.end(); ++it) { + minX = ((*it)[0] < minX) ? (*it)[0] : minX; + minY = ((*it)[1] < minY) ? (*it)[1] : minY; + maxX = ((*it)[0] > maxX) ? (*it)[0] : maxX; + maxY = ((*it)[1] > maxY) ? (*it)[1] : maxY; + } + //Store the bounding box + this->bbox.setBounds(SbVec3f(minX, minY, 0.f), SbVec3f (maxX, maxY, 0.f)); } - SbVec3f surfNorm(0.f, 0.f, 1.f) ; - //Get the camera z-direction - SbVec3f z = vv.zVector(); - const SbViewportRegion & vpr = SoViewportRegionElement::get(state); + if(hasText) { - SoGetMatrixAction * getmatrixaction = new SoGetMatrixAction(vpr); - getmatrixaction->apply(this); + const unsigned char * dataptr = this->image.getValue(size, nc); - SbMatrix transform = getmatrixaction->getMatrix(); - transform.multVecMatrix(surfNorm, surfNorm); + SbVec3f surfNorm(0.f, 0.f, 1.f) ; + //Get the camera z-direction + SbVec3f z = vv.zVector(); + const SbViewportRegion & vpr = SoViewportRegionElement::get(state); - bool flip = surfNorm.dot(z) > 0; + SoGetMatrixAction * getmatrixaction = new SoGetMatrixAction(vpr); + getmatrixaction->apply(this); - glDisable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); // Enable Textures - glEnable(GL_BLEND); + SbMatrix transform = getmatrixaction->getMatrix(); + transform.multVecMatrix(surfNorm, surfNorm); - // Copy the text bitmap into memory and bind - GLuint myTexture; - // generate a texture - glGenTextures(1, &myTexture); + bool flip = surfNorm.dot(z) > 0; - glBindTexture(GL_TEXTURE_2D, myTexture); + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); // Enable Textures + glEnable(GL_BLEND); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // Copy the text bitmap into memory and bind + GLuint myTexture; + // generate a texture + glGenTextures(1, &myTexture); - glTexImage2D(GL_TEXTURE_2D, 0, nc, srcw, srch, 0, GL_RGBA, GL_UNSIGNED_BYTE,(const GLvoid*) dataptr); + glBindTexture(GL_TEXTURE_2D, myTexture); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + glTexImage2D(GL_TEXTURE_2D, 0, nc, srcw, srch, 0, GL_RGBA, GL_UNSIGNED_BYTE,(const GLvoid*) dataptr); - // Apply a rotation and translation matrix - glTranslatef(textOffset[0],textOffset[1], textOffset[2]); - glRotatef((GLfloat) angle * 180 / M_PI, 0,0,1); - glBegin(GL_QUADS); - - glColor3f(1.f, 1.f, 1.f); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glTexCoord2f((flip) ? 0.f : 1.f, 1.f); glVertex2f( -this->imgWidth / 2, this->imgHeight / 2); - glTexCoord2f((flip) ? 0.f : 1.f, 0.f); glVertex2f( -this->imgWidth / 2, -this->imgHeight / 2); - glTexCoord2f((flip) ? 1.f : 0.f, 0.f); glVertex2f( this->imgWidth / 2, -this->imgHeight / 2); - glTexCoord2f((flip) ? 1.f : 0.f, 1.f); glVertex2f( this->imgWidth / 2, this->imgHeight / 2); - - glEnd(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + // Apply a rotation and translation matrix + glTranslatef(textOffset[0],textOffset[1], textOffset[2]); + glRotatef((GLfloat) angle * 180 / M_PI, 0,0,1); + glBegin(GL_QUADS); + + glColor3f(1.f, 1.f, 1.f); + + glTexCoord2f(flip ? 0.f : 1.f, 1.f); glVertex2f( -this->imgWidth / 2, this->imgHeight / 2); + glTexCoord2f(flip ? 0.f : 1.f, 0.f); glVertex2f( -this->imgWidth / 2, -this->imgHeight / 2); + glTexCoord2f(flip ? 1.f : 0.f, 0.f); glVertex2f( this->imgWidth / 2, -this->imgHeight / 2); + glTexCoord2f(flip ? 1.f : 0.f, 1.f); glVertex2f( this->imgWidth / 2, this->imgHeight / 2); + + glEnd(); + + // Reset the Mode + glPopMatrix(); + } - // Reset the Mode - glPopMatrix(); glPopAttrib(); state->pop(); } diff --git a/src/Mod/Sketcher/Gui/SoDatumLabel.h b/src/Mod/Sketcher/Gui/SoDatumLabel.h index 0fa276198..a57f8b37c 100644 --- a/src/Mod/Sketcher/Gui/SoDatumLabel.h +++ b/src/Mod/Sketcher/Gui/SoDatumLabel.h @@ -47,11 +47,13 @@ class SketcherGuiExport SoDatumLabel : public SoShape { public: enum Type { + ANGLE, DISTANCE, DISTANCEX, DISTANCEY, - ANGLE, - RADIUS}; + RADIUS, + SYMMETRIC + }; static void initClass(); SoDatumLabel(); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index fcdc384d2..caeb79b03 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -1428,6 +1428,7 @@ void ViewProviderSketch::updateColor(void) ConstraintType type = getSketchObject()->Constraints.getValues()[i]->Type; bool hasDatumLabel = (type == Sketcher::Angle || type == Sketcher::Radius || + type == Sketcher::Symmetric || type == Sketcher::Distance || type == Sketcher::DistanceX || type == Sketcher::DistanceY); @@ -1527,7 +1528,7 @@ void ViewProviderSketch::drawConstraintIcons() break; case Symmetric: icoType = QString::fromAscii("small/Constraint_Symmetric_sm"); - index1 = 3; + index1 = 2; break; default: continue; // Icon shouldn't be generated @@ -2252,34 +2253,18 @@ Restart: dir.normalize(); SbVec3f norm (-dir[1],dir[0],0); - // Get the datum nodes - SoSeparator *sepArrows = dynamic_cast(sep->getChild(1)); - SoCoordinate3 *arrowsCord = dynamic_cast(sepArrows->getChild(0)); + SoDatumLabel *asciiText = dynamic_cast(sep->getChild(0)); + asciiText->datumtype = SoDatumLabel::SYMMETRIC; - arrowsCord->point.setNum(10); + asciiText->pnts.setNum(2); + SbVec3f *verts = asciiText->pnts.startEditing(); - // Calculate coordinates for the first arrow - arrowsCord->point.set1Value(0,p1); - arrowsCord->point.set1Value(1,p1 + dir * 5); - arrowsCord->point.set1Value(2,p1 + dir * 3 + norm * 2); - arrowsCord->point.set1Value(3,p1 + dir * 5); - arrowsCord->point.set1Value(4,p1 + dir * 3 - norm * 2); + verts[0] = p1; + verts[1] = p2; - // Calculate coordinates for the second arrow - arrowsCord->point.set1Value(5,p2); - arrowsCord->point.set1Value(6,p2 - dir * 5); - arrowsCord->point.set1Value(7,p2 - dir * 3 + norm * 2); - arrowsCord->point.set1Value(8,p2 - dir * 5); - arrowsCord->point.set1Value(9,p2 - dir * 3 - norm * 2); + asciiText->pnts.finishEditing(); - // Use the coordinates calculated earlier to the lineset - SoLineSet *arrowsLineSet = dynamic_cast(sepArrows->getChild(1)); - arrowsLineSet->numVertices.set1Value(0,3); - arrowsLineSet->numVertices.set1Value(1,2); - arrowsLineSet->numVertices.set1Value(2,3); - arrowsLineSet->numVertices.set1Value(3,2); - - dynamic_cast(sep->getChild(2))->translation = (p1 + p2)/2; + dynamic_cast(sep->getChild(1))->translation = (p1 + p2)/2; } break; case Angle: @@ -2508,16 +2493,13 @@ void ViewProviderSketch::rebuildConstraintsVisual(void) break; case Symmetric: { - SoSeparator *sepArrows = new SoSeparator(); - sepArrows->addChild(new SoCoordinate3()); - SoLineSet *lineSet = new SoLineSet; - sepArrows->addChild(lineSet); - sep->addChild(Material); - sep->addChild(sepArrows); // 1. + SoDatumLabel *arrows = new SoDatumLabel(); + arrows->string = ""; + arrows->textColor = ConstrDimColor; - // Add new nodes to Constraint Seperator - sep->addChild(new SoTranslation()); // 2. - sep->addChild(new SoImage()); // 3. constraint icon + sep->addChild(arrows); // 0. + sep->addChild(new SoTranslation()); // 1. + sep->addChild(new SoImage()); // 2. constraint icon edit->vConstrType.push_back((*it)->Type); }