Sketcher, 0000466: improve visualization of constraints

This commit is contained in:
mrlukeparry 2012-07-15 13:23:59 +02:00 committed by logari81
parent e5953cedac
commit da7528c5b9
5 changed files with 697 additions and 359 deletions

View File

@ -51,7 +51,8 @@ Constraint::Constraint()
SecondPos(none),
Third(GeoUndef),
ThirdPos(none),
LabelDistance(10.f)
LabelDistance(10.f),
LabelPosition(0.f)
{
}
@ -65,7 +66,8 @@ Constraint::Constraint(const Constraint& from)
SecondPos(from.SecondPos),
Third(from.Third),
ThirdPos(from.ThirdPos),
LabelDistance(from.LabelDistance)
LabelDistance(from.LabelDistance),
LabelPosition(from.LabelPosition)
{
}
@ -100,7 +102,8 @@ void Constraint::Save (Writer &writer) const
<< "SecondPos=\"" << (int) SecondPos << "\" "
<< "Third=\"" << Third << "\" "
<< "ThirdPos=\"" << (int) ThirdPos << "\" "
<< "LabelDistance=\"" << LabelDistance<< "\" />"
<< "LabelDistance=\"" << LabelDistance << "\" "
<< "LabelPosition=\"" << LabelPosition << "\" />"
<< std::endl;
}
@ -123,4 +126,7 @@ void Constraint::Restore(XMLReader &reader)
// Read the distance a constraint label has been moved
if (reader.hasAttribute("LabelDistance"))
LabelDistance = (float)reader.getAttributeAsFloat("LabelDistance");
if (reader.hasAttribute("LabelPosition"))
LabelPosition = (float)reader.getAttributeAsFloat("LabelPosition");
}

View File

@ -83,6 +83,7 @@ public:
int Third;
PointPos ThirdPos;
float LabelDistance;
float LabelPosition;
};
} //namespace Sketcher

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (c) 2011 *
* Copyright (c) 2011-2012 Luke Parry <l.parry@warwick.ac.uk> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@ -45,6 +45,7 @@
# include <math.h>
#endif
#include <Inventor/actions/SoGetMatrixAction.h>
#include <Inventor/elements/SoFontNameElement.h>
#include <Inventor/elements/SoFontSizeElement.h>
#include <Inventor/elements/SoModelMatrixElement.h>
@ -73,11 +74,23 @@ SoDatumLabel::SoDatumLabel()
SO_NODE_CONSTRUCTOR(SoDatumLabel);
SO_NODE_ADD_FIELD(string, (""));
SO_NODE_ADD_FIELD(textColor, (SbVec3f(1.0f,1.0f,1.0f)));
SO_NODE_ADD_FIELD(name, ("Helvetica"));
SO_NODE_ADD_FIELD(size, (12));
SO_NODE_ADD_FIELD(pnts, (SbVec3f(.0f,.0f,.0f)));
this->bbx = 0;
this->bby = 0;
SO_NODE_ADD_FIELD(name, ("Helvetica"));
SO_NODE_ADD_FIELD(size, (12.f));
SO_NODE_ADD_FIELD(lineWidth, (2.f));
SO_NODE_ADD_FIELD(datumtype, (SoDatumLabel::DISTANCE));
SO_NODE_DEFINE_ENUM_VALUE(Type, DISTANCE);
SO_NODE_DEFINE_ENUM_VALUE(Type, DISTANCEX);
SO_NODE_DEFINE_ENUM_VALUE(Type, DISTANCEY);
SO_NODE_DEFINE_ENUM_VALUE(Type, ANGLE);
SO_NODE_DEFINE_ENUM_VALUE(Type, RADIUS);
SO_NODE_SET_SF_ENUM_TYPE(datumtype, Type);
this->imgWidth = 0;
this->imgHeight = 0;
}
void SoDatumLabel::drawImage()
@ -123,103 +136,199 @@ void SoDatumLabel::drawImage()
void SoDatumLabel::computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
{
SbVec2s size;
int nc;
const unsigned char * dataptr = this->image.getValue(size, nc);
if (dataptr == NULL) {
box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
center.setValue(0.0f,0.0f,0.0f);
return;
}
float srcw = size[0];
float srch = size[1];
float height, width;
if(action->getTypeId() == SoGLRenderAction::getClassTypeId()) {
// Update using the GL state
SoState *state = action->getState();
float srcw = size[0];
float srch = size[1];
const SbViewVolume & vv = SoViewVolumeElement::get(state);
float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.5f);
float aspectRatio = (float) srcw / (float) srch;
float height = scale / (float) srch;
float width = aspectRatio * (float) height;
// Update stored values
this->bbx = width;
this->bby = height;
} else {
// Update Primitives using stored dimensions
width = this->bbx;
height = this->bby;
}
SbVec3f min (-width / 2, -height / 2, 0.f);
SbVec3f max (width / 2, height / 2, 0.f);
box.setBounds(min, max);
center.setValue(0.f,0.f,0.f);
// Set the bounding box using stored parameters
box.setBounds(this->bbox.getMin(),this->bbox.getMax() );
SbVec3f bbcenter = this->bbox.getCenter();
center.setValue(bbcenter[0], bbcenter[1], bbcenter[2]);
}
void SoDatumLabel::generatePrimitives(SoAction * action)
{
// Get the size
SbVec2s size;
int nc;
const unsigned char * dataptr = this->image.getValue(size, nc);
if (dataptr == NULL)
return;
float width, height;
// Initialisation check (needs something more sensible) prevents an infinite loop bug
if(this->imgHeight <= FLT_EPSILON || this->imgWidth <= FLT_EPSILON)
return;
if (action->getTypeId() == SoGLRenderAction::getClassTypeId()) {
// Update using the GL state
SoState *state = action->getState();
float srcw = size[0];
float srch = size[1];
// Get the points stored
const SbVec3f *pnts = this->pnts.getValues(0);
SbVec3f p1 = pnts[0];
SbVec3f p2 = pnts[1];
const SbViewVolume & vv = SoViewVolumeElement::get(state);
float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.5f);
float offsetX, offsetY;
float aspectRatio = (float) srcw / (float) srch;
float height = scale / (float) srch;
float width = aspectRatio * (float) height;
// Change the offset and bounding box parameters depending on Datum Type
if(this->datumtype.getValue() == DISTANCE || this->datumtype.getValue() == DISTANCEX || this->datumtype.getValue() == DISTANCEY ){
// Update stored dimensions
this->bbx = width;
this->bby = height;
} else {
// Update Primitives using stored dimensions
width = this->bbx;
height = this->bby;
float length = this->param1.getValue();
float length2 = this->param2.getValue();
SbVec3f dir, norm;
if (this->datumtype.getValue() == DISTANCE) {
dir = (p2-p1);
} else if (this->datumtype.getValue() == DISTANCEX) {
dir = SbVec3f( (p2[0] - p1[0] >= FLT_EPSILON) ? 1 : -1, 0, 0);
} else if (this->datumtype.getValue() == DISTANCEY) {
dir = SbVec3f(0, (p2[1] - p1[1] >= FLT_EPSILON) ? 1 : -1, 0);
}
dir.normalize();
norm = SbVec3f (-dir[1],dir[0],0);
float normproj12 = (p2-p1).dot(norm);
SbVec3f p1_ = p1 + normproj12 * norm;
SbVec3f midpos = (p1_ + p2)/2;
// Get magnitude of angle between horizontal
float angle = atan2f(dir[1],dir[0]);
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.f);
SbVec3f img3 = SbVec3f( this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img4 = SbVec3f( this->imgWidth / 2, this->imgHeight / 2, 0.f);
// Rotate through an angle
float s = sin(angle);
float c = cos(angle);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), 0.f);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), 0.f);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), 0.f);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), 0.f);
SbVec3f textOffset = midpos + norm * length + dir * length2;
img1 += textOffset;
img2 += textOffset;
img3 += textOffset;
img4 += textOffset;
// Primitive Shape is only for text as this should only be selectable
SoPrimitiveVertex pv;
this->beginShape(action, QUADS);
pv.setNormal( SbVec3f(0.f, 0.f, 1.f) );
// Set coordinates
pv.setPoint( img1 );
shapeVertex(&pv);
pv.setPoint( img2 );
shapeVertex(&pv);
pv.setPoint( img3 );
shapeVertex(&pv);
pv.setPoint( img4 );
shapeVertex(&pv);
this->endShape();
} else if (this->datumtype.getValue() == RADIUS) {
SbVec3f dir = (p2-p1);
dir.normalize();
SbVec3f norm (-dir[1],dir[0],0);
float length = this->param1.getValue();
SbVec3f pos = p2 + length*dir;
float angle = atan2f(dir[1],dir[0]);
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.f);
SbVec3f img3 = SbVec3f( this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img4 = SbVec3f( this->imgWidth / 2, this->imgHeight / 2, 0.f);
// Rotate through an angle
float s = sin(angle);
float c = cos(angle);
img1 = SbVec3f((img1[0] * c) - (img1[1] * s), (img1[0] * s) + (img1[1] * c), 0.f);
img2 = SbVec3f((img2[0] * c) - (img2[1] * s), (img2[0] * s) + (img2[1] * c), 0.f);
img3 = SbVec3f((img3[0] * c) - (img3[1] * s), (img3[0] * s) + (img3[1] * c), 0.f);
img4 = SbVec3f((img4[0] * c) - (img4[1] * s), (img4[0] * s) + (img4[1] * c), 0.f);
SbVec3f textOffset = pos;
img1 += textOffset;
img2 += textOffset;
img3 += textOffset;
img4 += textOffset;
// Primitive Shape is only for text as this should only be selectable
SoPrimitiveVertex pv;
this->beginShape(action, QUADS);
pv.setNormal( SbVec3f(0.f, 0.f, 1.f) );
// Set coordinates
pv.setPoint( img1 );
shapeVertex(&pv);
pv.setPoint( img2 );
shapeVertex(&pv);
pv.setPoint( img3 );
shapeVertex(&pv);
pv.setPoint( img4 );
shapeVertex(&pv);
this->endShape();
} else if (this->datumtype.getValue() == ANGLE) {
// Only the angle intersection point is needed
SbVec3f p0 = pnts[0];
// Load the Paramaters
float length = this->param1.getValue();
float startangle = this->param2.getValue();
float range = this->param3.getValue();
float endangle = startangle + range;
float r = 2*length;
// Useful Information
// v0 - vector for text position
// p0 - vector for angle intersect
SbVec3f v0(cos(startangle+range/2),sin(startangle+range/2),0);
SbVec3f textOffset = p0 + v0 * r;
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.f);
SbVec3f img3 = SbVec3f( this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img4 = SbVec3f( this->imgWidth / 2, this->imgHeight / 2, 0.f);
img1 += textOffset;
img2 += textOffset;
img3 += textOffset;
img4 += textOffset;
// Primitive Shape is only for text as this should only be selectable
SoPrimitiveVertex pv;
this->beginShape(action, QUADS);
pv.setNormal( SbVec3f(0.f, 0.f, 1.f) );
// Set coordinates
pv.setPoint( img1 );
shapeVertex(&pv);
pv.setPoint( img2 );
shapeVertex(&pv);
pv.setPoint( img3 );
shapeVertex(&pv);
pv.setPoint( img4 );
shapeVertex(&pv);
this->endShape();
}
SoPrimitiveVertex pv;
beginShape(action, QUADS);
pv.setNormal( SbVec3f(0.f, 0.f, 1.f) );
// Set coordinates
pv.setPoint( SbVec3f(-width / 2, height / 2, 0.f) );
shapeVertex(&pv);
pv.setPoint( SbVec3f(-width / 2, -height / 2, 0.f) );
shapeVertex(&pv);
pv.setPoint( SbVec3f(width / 2, -height / 2, 0.f) );
shapeVertex(&pv);
pv.setPoint( SbVec3f(width / 2, height / 2, 0.f) );
shapeVertex(&pv);
endShape();
}
void SoDatumLabel::GLRender(SoGLRenderAction * action)
@ -239,13 +348,384 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action)
int srcw = size[0];
int srch = size[1];
// Create the quad to hold texture
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;
// Get the points stored
const SbVec3f *pnts = this->pnts.getValues(0);
state->push();
//Set General OpenGL Properties
glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
//Enable Anti-alias
if(action->isSmoothing())
{
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
}
// Position for Datum Text Label
float offsetX, offsetY, angle;
SbVec3f textOffset;
if(this->datumtype.getValue() == DISTANCE || this->datumtype.getValue() == DISTANCEX || this->datumtype.getValue() == DISTANCEY )
{
float length = this->param1.getValue();
float length2 = this->param2.getValue();
const SbVec3f *pnts = this->pnts.getValues(0);
SbVec3f p1 = pnts[0];
SbVec3f p2 = pnts[1];
SbVec3f dir, norm;
if (this->datumtype.getValue() == DISTANCE) {
dir = (p2-p1);
} else if (this->datumtype.getValue() == DISTANCEX) {
dir = SbVec3f( (p2[0] - p1[0] >= FLT_EPSILON) ? 1 : -1, 0, 0);
} else if (this->datumtype.getValue() == DISTANCEY) {
dir = SbVec3f(0, (p2[1] - p1[1] >= FLT_EPSILON) ? 1 : -1, 0);
}
dir.normalize();
norm = SbVec3f (-dir[1],dir[0],0);
// when the datum line is not parallel to p1-p2 the projection of
// p1-p2 on norm is not zero, p2 is considered as reference and p1
// is replaced by its projection p1_
float normproj12 = (p2-p1).dot(norm);
SbVec3f p1_ = p1 + normproj12 * norm;
SbVec3f midpos = (p1_ + p2)/2;
float offset1 = (length + normproj12 < 0) ? -0.02 : 0.02;
float offset2 = (length < 0) ? -0.02 : 0.02;
// Get magnitude of angle between horizontal
angle = atan2f(dir[1],dir[0]);
bool flip=false;
if (angle > M_PI_2+M_PI/12) {
angle -= M_PI;
flip = true;
} else if (angle <= -M_PI_2+M_PI/12) {
angle += M_PI;
flip = true;
}
textOffset = midpos + norm * length + dir * length2;
// 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;
SbVec3f perp1 = p1_ + norm * (length + offset1 * scale);
SbVec3f perp2 = p2 + norm * (length + offset2 * scale);
// Calculate the coordinates for the parallel datum lines
SbVec3f par1 = p1_ + norm * length;
SbVec3f par2 = midpos + norm * length + dir * (length2 - this->imgWidth / 2 - margin);
SbVec3f par3 = midpos + norm * length + dir * (length2 + this->imgWidth / 2 + margin);
SbVec3f par4 = p2 + norm * length;
bool flipTriang = false;
if ((par3-par1).dot(dir) > (par4 - par1).length()) {
// Increase Margin to improve visability
float tmpMargin = 0.08f * scale;
par3 = par4;
if((par2-par1).dot(dir) > (par4 - par1).length()) {
par3 = par2;
par2 = par1 - dir * tmpMargin;
flipTriang = true;
}
} else if ((par2-par1).dot(dir) < 0.f) {
float tmpMargin = 0.08f * scale;
par2 = par1;
if((par3-par1).dot(dir) < 0.f) {
par2 = par3;
par3 = par4 + dir * tmpMargin;
flipTriang = true;
}
}
// Perp Lines
glBegin(GL_LINES);
glVertex2f(p1[0], p1[1]);
glVertex2f(perp1[0], perp1[1]);
glVertex2f(p2[0], p2[1]);
glVertex2f(perp2[0], perp2[1]);
glVertex2f(par1[0], par1[1]);
glVertex2f(par2[0], par2[1]);
glVertex2f(par3[0], par3[1]);
glVertex2f(par4[0], par4[1]);
glEnd();
SbVec3f ar1 = par1 + ((flipTriang) ? -1 : 1) * dir * 0.866 * 2 * margin;
SbVec3f ar2 = ar1 + norm * margin;
ar1 -= norm * margin;
SbVec3f ar3 = par4 - ((flipTriang) ? -1 : 1) * dir * 0.866 * 2 * margin;
SbVec3f ar4 = ar3 + norm * margin ;
ar3 -= norm * margin;
//Draw a pretty arrowhead (Equilateral) (Eventually could be improved to other shapes?)
glBegin(GL_TRIANGLES);
glVertex2f(par1[0], par1[1]);
glVertex2f(ar1[0], ar1[1]);
glVertex2f(ar2[0], ar2[1]);
glVertex2f(par4[0], par4[1]);
glVertex2f(ar3[0], ar3[1]);
glVertex2f(ar4[0], ar4[1]);
glEnd();
// BOUNDING BOX CALCULATION - IMPORTANT
// Finds the mins and maxes
std::vector<SbVec3f> corners;
corners.push_back(p1);
corners.push_back(p2);
corners.push_back(perp1);
corners.push_back(perp2);
float minX = p1[0], minY = p1[1], maxX = p1[0] , maxY = p1[1];
for (std::vector<SbVec3f>::const_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));
} else if (this->datumtype.getValue() == RADIUS) {
// Get the Points
SbVec3f p1 = pnts[0];
SbVec3f p2 = pnts[1];
SbVec3f dir = (p2-p1);
dir.normalize();
SbVec3f norm (-dir[1],dir[0],0);
float length = this->param1.getValue();
SbVec3f pos = p2 + length*dir;
// Get magnitude of angle between horizontal
angle = atan2f(dir[1],dir[0]);
bool flip=false;
if (angle > M_PI_2+M_PI/12) {
angle -= M_PI;
flip = true;
} else if (angle <= -M_PI_2+M_PI/12) {
angle += M_PI;
flip = true;
}
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;
// Create the arrowhead
SbVec3f ar0 = p2;
SbVec3f ar1 = p2 - dir * 0.866 * 2 * margin;
SbVec3f ar2 = ar1 + norm * margin;
ar1 -= norm * margin;
SbVec3f p3 = pos + dir * (this->imgWidth / 2 + margin);
if ((p3-p1).length() > (p2-p1).length())
p2 = p3;
// Calculate the points
SbVec3f pnt1 = pos - dir * (margin + this->imgWidth / 2);
SbVec3f pnt2 = pos + dir * (margin + this->imgWidth / 2);
// Draw the Lines
glBegin(GL_LINES);
glVertex2f(p1[0], p1[1]);
glVertex2f(pnt1[0], pnt1[1]);
glVertex2f(pnt2[0], pnt2[1]);
glVertex2f(p2[0], p2[1]);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2f(ar0[0], ar0[1]);
glVertex2f(ar1[0], ar1[1]);
glVertex2f(ar2[0], ar2[1]);
glEnd();
// BOUNDING BOX CALCULATION - IMPORTANT
// Finds the mins and maxes
std::vector<SbVec3f> corners;
corners.push_back(p1);
corners.push_back(p2);
corners.push_back(pnt1);
corners.push_back(pnt2);
float minX = p1[0], minY = p1[1], maxX = p1[0] , maxY = p1[1];
for (std::vector<SbVec3f>::const_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));
} else if (this->datumtype.getValue() == ANGLE) {
// Only the angle intersection point is needed
SbVec3f p0 = pnts[0];
// Load the Paramaters
float length = this->param1.getValue();
float startangle = this->param2.getValue();
float range = this->param3.getValue();
float endangle = startangle + range;
float r = 2*length;
// Set the Text label angle to zero
angle = 0.f;
// Useful Information
// v0 - vector for text position
// p0 - vector for angle intersect
SbVec3f v0(cos(startangle+range/2),sin(startangle+range/2),0);
// leave some space for the text
if (range >= 0)
range = std::max(0.2f*range, range - this->imgWidth/(2*r));
else
range = std::min(0.2f*range, range + this->imgWidth/(2*r));
int countSegments = std::max(6, abs(int(50.0 * range / (2 * M_PI))));
double segment = range / (2*countSegments-2);
textOffset = p0 + v0 * r;
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);
int i=0;
for (; i < countSegments; i++) {
double theta = startangle + segment*i;
SbVec3f v1 = p0+SbVec3f(r*cos(theta),r*sin(theta),0);
glVertex2f(v1[0],v1[1]);
}
glEnd();
glBegin(GL_LINE_STRIP);
i=0;
for (; i < countSegments; i++) {
double theta = endangle - segment*i;
SbVec3f v1 = p0+SbVec3f(r*cos(theta),r*sin(theta),0);
glVertex2f(v1[0],v1[1]);
}
glEnd();
// Direction vectors for start and end lines
SbVec3f v1(cos(startangle),sin(startangle),0);
SbVec3f v2(cos(endangle),sin(endangle),0);
SbVec3f pnt1 = p0+(r-margin)*v1;
SbVec3f pnt2 = p0+(r+margin)*v1;
SbVec3f pnt3 = p0+(r-margin)*v2;
SbVec3f pnt4 = p0+(r+margin)*v2;
glBegin(GL_LINES);
glVertex2f(pnt1[0],pnt1[1]);
glVertex2f(pnt2[0],pnt2[1]);
glVertex2f(pnt3[0],pnt3[1]);
glVertex2f(pnt4[0],pnt4[1]);
glEnd();
// BOUNDING BOX CALCULATION - IMPORTANT
// Finds the mins and maxes
// We may need to include the text position too
SbVec3f img1 = SbVec3f(-this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img2 = SbVec3f(-this->imgWidth / 2, this->imgHeight / 2, 0.f);
SbVec3f img3 = SbVec3f( this->imgWidth / 2, -this->imgHeight / 2, 0.f);
SbVec3f img4 = SbVec3f( this->imgWidth / 2, this->imgHeight / 2, 0.f);
img1 += textOffset;
img2 += textOffset;
img3 += textOffset;
img4 += textOffset;
std::vector<SbVec3f> corners;
corners.push_back(pnt1);
corners.push_back(pnt2);
corners.push_back(pnt3);
corners.push_back(pnt4);
corners.push_back(img1);
corners.push_back(img2);
corners.push_back(img3);
corners.push_back(img4);
float minX = pnt1[0], minY = pnt1[1], maxX = pnt1[0] , maxY = pnt1[1];
for (std::vector<SbVec3f>::const_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);
SoGetMatrixAction * getmatrixaction = new SoGetMatrixAction(vpr);
getmatrixaction->apply(this);
SbMatrix transform = getmatrixaction->getMatrix();
transform.multVecMatrix(surfNorm, surfNorm);
bool flip = surfNorm.dot(z) > 0;
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D); // Enable Textures
glEnable(GL_BLEND);
glEnable(GL_BLEND);
// Copy the text bitmap into memory and bind
GLuint myTexture;
// generate a texture
@ -259,27 +739,26 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action)
glTexImage2D(GL_TEXTURE_2D, 0, nc, srcw, srch, 0, GL_RGBA, GL_UNSIGNED_BYTE,(const GLvoid*) dataptr);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Create the quad to hold texture
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;
float height = scale / (float) srch;
float width = aspectRatio * (float) height;
this->bbx = width;
this->bby = height;
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(0.f, 1.f); glVertex2f(-width/ 2, height / 2);
glTexCoord2f(0.f, 0.f); glVertex2f(-width / 2,-height / 2);
glTexCoord2f(1.f, 0.f); glVertex2f( width/ 2,-height / 2);
glTexCoord2f(1.f, 1.f); glVertex2f( width / 2, height / 2);
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();
glPopAttrib();
state->pop();
}

View File

@ -1,5 +1,5 @@
/***************************************************************************
* *
* Copyright (c) 2011-2012 Luke Parry <l.parry@warwick.ac.uk> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@ -33,27 +33,40 @@
#include <Inventor/fields/SoSFName.h>
#include <Inventor/fields/SoMFString.h>
#include <Inventor/fields/SoSFInt32.h>
#include <Inventor/fields/SoMFVec3f.h>
#include <Inventor/SbBox3f.h>
#include <Inventor/fields/SoSFImage.h>
namespace SketcherGui {
class SketcherGuiExport SoDatumLabel : public SoShape {
typedef SoShape inherited;
SO_NODE_HEADER(SoDatumLabel);
public:
enum Type
{
DISTANCE,
DISTANCEX,
DISTANCEY,
ANGLE,
RADIUS};
static void initClass();
SoDatumLabel();
SoMFString string;
SoSFColor textColor;
SoSFEnum justification;
SoSFEnum datumtype;
SoSFName name;
SoSFInt32 size;
SoSFFloat param1;
SoSFFloat param2;
SoSFFloat param3;
SoMFVec3f pnts;
SoSFImage image;
SoSFFloat lineWidth;
protected:
virtual ~SoDatumLabel() {};
@ -63,8 +76,9 @@ protected:
private:
void drawImage();
float bbx;
float bby;
SbBox3f bbox;
float imgWidth;
float imgHeight;
};
}

View File

@ -46,6 +46,7 @@
# include <Inventor/nodes/SoAsciiText.h>
# include <Inventor/nodes/SoTransform.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoAnnotation.h>
# include <Inventor/nodes/SoVertexProperty.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoText2.h>
@ -395,7 +396,6 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe
//Base::Console().Log("start dragging, point:%d\n",this->DragPoint);
Mode = STATUS_SELECT_Constraint;
done = true;
}
if (done && length < dblClickRadius && tmp.getValue() < dci) {
@ -418,8 +418,7 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe
default:
return false;
}
}
else {
} else {
// Do things depending on the mode of the user interaction
switch (Mode) {
case STATUS_SELECT_Point:
@ -922,8 +921,9 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
double radius = circle->getRadius();
double angle = M_PI/4;
p1 = circle->getCenter();
Base::Vector3d tmpDir = Base::Vector3d(toPos.fX, toPos.fY, 0) - p1;
double angle = atan2f(tmpDir.y, tmpDir.x);
p2 = p1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
} else
return;
@ -940,11 +940,17 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
else if (Constr->Type == DistanceY)
dir = Base::Vector3d(0, (p2.y - p1.y >= FLT_EPSILON) ? 1 : -1, 0);
if (Constr->Type == Radius)
if (Constr->Type == Radius) {
Constr->LabelDistance = vec.x * dir.x + vec.y * dir.y;
else {
Constr->LabelPosition = atan2f(dir.y, dir.x);
} else {
Base::Vector3d norm(-dir.y,dir.x,0);
Constr->LabelDistance = vec.x * norm.x + vec.y * norm.y;
if (Constr->Type == Distance ||
Constr->Type == DistanceX || Constr->Type == DistanceY) {
vec = Base::Vector3d(toPos.fX, toPos.fY, 0) - (p2 + p1) / 2;
Constr->LabelPosition = vec.x * dir.x + vec.y * dir.y;
}
}
}
else if (Constr->Type == Angle) {
@ -1018,11 +1024,11 @@ bool ViewProviderSketch::isConstraintAtPosition(const Base::Vector3d &constrPos,
if (pp) {
SoPath *path = pp->getPath();
int length = path->getLength();
SoNode *tailFather = path->getNode(length-2);
SoNode *tailFather1 = path->getNode(length-2);
SoNode *tailFather2 = path->getNode(length-3);
// checking if a constraint is the same as the one selected
if (tailFather2 == constraint || tailFather == constraint) {
if (tailFather1 == constraint || tailFather2 == constraint) {
return false;
} else {
return true;
@ -1414,33 +1420,42 @@ void ViewProviderSketch::updateColor(void)
// colors of the constraints
for (int i=0; i < edit->constrGroup->getNumChildren(); i++) {
SoSeparator *s = dynamic_cast<SoSeparator *>(edit->constrGroup->getChild(i));
SoMaterial *m = dynamic_cast<SoMaterial *>(s->getChild(0));
// Check Constraint Type
ConstraintType type = getSketchObject()->Constraints.getValues()[i]->Type;
bool hasDatumLabel = (type == Sketcher::Angle ||
type == Sketcher::Radius ||
type == Sketcher::Distance || type == Sketcher::DistanceX || type == Sketcher::DistanceY);
type == Sketcher::Radius ||
type == Sketcher::Distance ||
type == Sketcher::DistanceX || type == Sketcher::DistanceY);
// Non DatumLabel Nodes will have a material excluding coincident
bool hasMaterial = false;
SoMaterial *m;
if (!hasDatumLabel && type != Sketcher::Coincident) {
hasMaterial = true;
m = dynamic_cast<SoMaterial *>(s->getChild(0));
}
if (edit->SelConstraintSet.find(i) != edit->SelConstraintSet.end()) {
m->diffuseColor = SelectColor;
if (hasDatumLabel) {
SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(4));
SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(0));
l->textColor = SelectColor;
}
} else if (hasMaterial)
m->diffuseColor = SelectColor;
} else if (edit->PreselectConstraint == i) {
m->diffuseColor = PreselectColor;
if (hasDatumLabel) {
SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(4));
SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(0));
l->textColor = PreselectColor;
}
} else if (hasMaterial)
m->diffuseColor = PreselectColor;
}
else {
m->diffuseColor = ConstrDimColor;
if (hasDatumLabel) {
SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(4));
SoDatumLabel *l = dynamic_cast<SoDatumLabel *>(s->getChild(0));
l->textColor = ConstrDimColor;
}
} else if (hasMaterial)
m->diffuseColor = ConstrDimColor;
}
}
@ -1729,7 +1744,6 @@ void ViewProviderSketch::draw(bool temp)
edit->CurvIdToGeoId.push_back(GeoId);
}
else {
;
}
}
@ -2071,28 +2085,7 @@ Restart:
} else
break;
SbVec3f p1(pnt1.x,pnt1.y,zConstr);
SbVec3f p2(pnt2.x,pnt2.y,zConstr);
SbVec3f dir, norm;
if (Constr->Type == Distance)
dir = (p2-p1);
else if (Constr->Type == DistanceX)
dir = SbVec3f( (pnt2.x - pnt1.x >= FLT_EPSILON) ? 1 : -1, 0, 0);
else if (Constr->Type == DistanceY)
dir = SbVec3f(0, (pnt2.y - pnt1.y >= FLT_EPSILON) ? 1 : -1, 0);
dir.normalize();
norm = SbVec3f (-dir[1],dir[0],0);
// when the datum line is not parallel to p1-p2 the projection of
// p1-p2 on norm is not zero, p2 is considered as reference and p1
// is replaced by its projection p1_
float normproj12 = (p2-p1).dot(norm);
SbVec3f p1_ = p1 + normproj12 * norm;
SbVec3f midpos = (p1_ + p2)/2;
SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(4));
SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(0));
if ((Constr->Type == DistanceX || Constr->Type == DistanceY) &&
Constr->FirstPos != Sketcher::none && Constr->Second == Constraint::GeoUndef)
// display negative sign for absolute coordinates
@ -2100,68 +2093,25 @@ Restart:
else // hide negative sign
asciiText->string = SbString().sprintf("%.2f",std::abs(Constr->Value));
// Get Bounding box dimensions for Datum text
Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
if (Constr->Type == Distance)
asciiText->datumtype = SoDatumLabel::DISTANCE;
else if (Constr->Type == DistanceX)
asciiText->datumtype = SoDatumLabel::DISTANCEX;
else if (Constr->Type == DistanceY)
asciiText->datumtype = SoDatumLabel::DISTANCEY;
// [FIX ME] Its an attempt to find the height of the text using the bounding box, but is in correct.
SoGetBoundingBoxAction bbAction(viewer->getViewportRegion());
bbAction.apply(sep->getChild(4));
// Assign the Datum Points
asciiText->pnts.setNum(2);
SbVec3f *verts = asciiText->pnts.startEditing();
float bx,by,bz;
bbAction.getBoundingBox().getSize(bx,by,bz);
SbVec3f textBB(bx,by,bz);
// bbAction.setCenter(, true)
// This is the bounding box containing the width and height of text
verts[0] = SbVec3f (pnt1.x,pnt1.y,zConstr);
verts[1] = SbVec3f (pnt2.x,pnt2.y,zConstr);
SbVec3f textBBCenter = bbAction.getBoundingBox().getCenter();
asciiText->pnts.finishEditing();
float length = Constr->LabelDistance;
// Get magnitude of angle between horizontal
double angle = atan2f(dir[1],dir[0]);
bool flip=false;
if (angle > M_PI_2+M_PI/12) {
angle -= M_PI;
flip = true;
} else if (angle <= -M_PI_2+M_PI/12) {
angle += M_PI;
flip = true;
}
SbVec3f textpos = midpos + norm * (length + ( (flip ? 1:-1) * textBBCenter[1] / 4));
// set position and rotation of Datums Text
SoTransform *transform = dynamic_cast<SoTransform *>(sep->getChild(2));
transform->rotation.setValue(SbVec3f(0, 0, 1), (float)angle);
transform->translation.setValue(textpos);
// Get the datum nodes
SoSeparator *sepDatum = dynamic_cast<SoSeparator *>(sep->getChild(1));
SoCoordinate3 *datumCord = dynamic_cast<SoCoordinate3 *>(sepDatum->getChild(0));
// [Fixme] This should be made neater - compute the vertical datum line length
float offset1 = (length + normproj12 < 0) ? -0.5 : 0.5;
float offset2 = (length < 0) ? -0.5 : 0.5;
offset1 *= getScaleFactor();
offset2 *= getScaleFactor();
// Calculate coordinates for perpendicular datum lines
datumCord->point.set1Value(0,p1);
datumCord->point.set1Value(1,p1_ + norm * (length + offset1));
datumCord->point.set1Value(2,p2);
datumCord->point.set1Value(3,p2 + norm * (length + offset2));
// Calculate the coordinates for the parallel datum lines
datumCord->point.set1Value(4,p1_ + norm * length);
datumCord->point.set1Value(5,midpos + norm * length - dir * (textBB[0]/1.7f) );
datumCord->point.set1Value(6,midpos + norm * length + dir * (textBB[0]/1.7f) );
datumCord->point.set1Value(7,p2 + norm * length);
// Use the coordinates calculated earlier to the lineset
SoLineSet *datumLineSet = dynamic_cast<SoLineSet *>(sepDatum->getChild(1));
datumLineSet->numVertices.set1Value(0,2);
datumLineSet->numVertices.set1Value(1,2);
datumLineSet->numVertices.set1Value(2,2);
datumLineSet->numVertices.set1Value(3,2);
//Assign the Label Distance
asciiText->param1 = Constr->LabelDistance;
asciiText->param2 = Constr->LabelPosition;
}
break;
case PointOnObject:
@ -2385,68 +2335,20 @@ Restart:
} else
break;
SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(4));
asciiText->string = SbString().sprintf("%.2f",Base::toDegrees<double>(std::abs(Constr->Value)));
SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(0));
asciiText->string = SbString().sprintf("%.2f",Base::toDegrees<double>(std::abs(Constr->Value)));
asciiText->datumtype = SoDatumLabel::ANGLE;
asciiText->param1 = Constr->LabelDistance;
asciiText->param2 = startangle;
asciiText->param3 = range;
// Get Bounding box dimensions for Datum text
Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
asciiText->pnts.setNum(2);
SbVec3f *verts = asciiText->pnts.startEditing();
// [FIX ME] Its an attempt to find the height of the text using the bounding box, but is in correct.
SoGetBoundingBoxAction bbAction(viewer->getViewportRegion());
bbAction.apply(sep->getChild(4));
verts[0] = p0;
float bx,by,bz;
bbAction.getBoundingBox().getSize(bx,by,bz);
SbVec3f textBB(bx,by,bz);
asciiText->pnts.finishEditing();
SbVec3f textBBCenter = bbAction.getBoundingBox().getCenter();
float length = Constr->LabelDistance;
float r = 2*length;
SbVec3f v0(cos(startangle+range/2),sin(startangle+range/2),0);
SbVec3f textpos = p0 + v0 * r - SbVec3f(0,1,0) * textBBCenter[1]/4;
// leave some space for the text
if (range >= 0)
range = std::max(0.2*range, range - textBB[0]/(2*r));
else
range = std::min(0.2*range, range + textBB[0]/(2*r));
int countSegments = std::max(6, abs(int(50.0 * range / (2 * M_PI))));
double segment = range / (2*countSegments-2);
// set position and rotation of Datums Text
SoTransform *transform = dynamic_cast<SoTransform *>(sep->getChild(2));
transform->translation.setValue(textpos);
// Get the datum nodes
SoSeparator *sepDatum = dynamic_cast<SoSeparator *>(sep->getChild(1));
SoCoordinate3 *datumCord = dynamic_cast<SoCoordinate3 *>(sepDatum->getChild(0));
datumCord->point.setNum(2*countSegments+4);
int i=0;
int j=2*countSegments-1;
for (; i < countSegments; i++, j--) {
double angle = startangle + segment*i;
datumCord->point.set1Value(i,p0+SbVec3f(r*cos(angle),r*sin(angle),0));
angle = endangle - segment*i;
datumCord->point.set1Value(j,p0+SbVec3f(r*cos(angle),r*sin(angle),0));
}
SbVec3f v1(cos(startangle),sin(startangle),0);
SbVec3f v2(cos(endangle),sin(endangle),0);
float sf = getScaleFactor();
datumCord->point.set1Value(2*countSegments ,p0+(r-0.5f * sf)*v1);
datumCord->point.set1Value(2*countSegments+1,p0+(r+0.5f * sf)*v1);
datumCord->point.set1Value(2*countSegments+2,p0+(r-0.5f * sf)*v2);
datumCord->point.set1Value(2*countSegments+3,p0+(r+0.5f * sf)*v2);
// Use the coordinates calculated earlier to the lineset
SoLineSet *datumLineSet = dynamic_cast<SoLineSet *>(sepDatum->getChild(1));
datumLineSet->numVertices.set1Value(0,countSegments);
datumLineSet->numVertices.set1Value(1,countSegments);
datumLineSet->numVertices.set1Value(2,2);
datumLineSet->numVertices.set1Value(3,2);
}
break;
case Radius:
@ -2469,7 +2371,7 @@ Restart:
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
double radius = circle->getRadius();
double angle = M_PI/4;
double angle = (double) Constr->LabelPosition;
pnt1 = circle->getCenter();
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
} else
@ -2480,68 +2382,19 @@ Restart:
SbVec3f p1(pnt1.x,pnt1.y,zConstr);
SbVec3f p2(pnt2.x,pnt2.y,zConstr);
SbVec3f dir = (p2-p1);
dir.normalize();
SbVec3f norm (-dir[1],dir[0],0);
SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(0));
asciiText->string = SbString().sprintf("%.2f",Constr->Value);
asciiText->datumtype = SoDatumLabel::RADIUS;
asciiText->param1 = Constr->LabelDistance;
asciiText->param2 = Constr->LabelPosition;
float length = Constr->LabelDistance;
SbVec3f pos = p2 + length*dir;
asciiText->pnts.setNum(2);
SbVec3f *verts = asciiText->pnts.startEditing();
SoDatumLabel *asciiText = dynamic_cast<SoDatumLabel *>(sep->getChild(4));
asciiText->string = SbString().sprintf("%.2f",Constr->Value);
verts[0] = p1;
verts[1] = p2;
// Get Bounding box dimensions for Datum text
Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
// [FIX ME] Its an attempt to find the height of the text using the bounding box, but is in correct.
SoGetBoundingBoxAction bbAction(viewer->getViewportRegion());
bbAction.apply(sep->getChild(3));
float bx=0,by=0,bz=0;
SbBox3f bbox = bbAction.getBoundingBox();
if (!bbox.isEmpty())
bbox.getSize(bx,by,bz);
SbVec3f textBB(bx,by,bz);
SbVec3f textBBCenter = bbAction.getBoundingBox().getCenter();
// Get magnitude of angle between horizontal
double angle = atan2f(dir[1],dir[0]);
bool flip=false;
if (angle > M_PI_2+M_PI/12) {
angle -= M_PI;
flip = true;
} else if (angle <= -M_PI_2+M_PI/12) {
angle += M_PI;
flip = true;
}
SbVec3f textpos = pos + norm * ( (flip ? 1:-1) * textBBCenter[1] / 1.7f);
// set position and rotation of Datums Text
SoTransform *transform = dynamic_cast<SoTransform *>(sep->getChild(2));
transform->rotation.setValue(SbVec3f(0, 0, 1), (float)angle);
transform->translation.setValue(textpos);
// Get the datum nodes
SoSeparator *sepDatum = dynamic_cast<SoSeparator *>(sep->getChild(1));
SoCoordinate3 *datumCord = dynamic_cast<SoCoordinate3 *>(sepDatum->getChild(0));
SbVec3f p3 = pos + dir * (6+textBB[0]/1.7f);
if ((p3-p1).length() > (p2-p1).length())
p2 = p3;
// Calculate the coordinates for the parallel datum lines
datumCord->point.set1Value(0,p1);
datumCord->point.set1Value(1,pos - dir * (1+textBB[0]/1.7f) );
datumCord->point.set1Value(2,pos + dir * (1+textBB[0]/1.7f) );
datumCord->point.set1Value(3,p2);
// Use the coordinates calculated earlier to the lineset
SoLineSet *datumLineSet = dynamic_cast<SoLineSet *>(sepDatum->getChild(1));
datumLineSet->numVertices.set1Value(0,2);
datumLineSet->numVertices.set1Value(1,2);
asciiText->pnts.finishEditing();
}
break;
case Coincident: // nothing to do for coincident
@ -2575,10 +2428,10 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
SoSeparator *sep = new SoSeparator();
// no caching for fluctuand data structures
sep->renderCaching = SoSeparator::OFF;
// every constrained visual node gets its own material for preselection and selection
SoMaterial *Material = new SoMaterial;
Material->diffuseColor = ConstrDimColor;
sep->addChild(Material);
// distinguish different constraint types to build up
switch ((*it)->Type) {
@ -2588,35 +2441,22 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
case Radius:
case Angle:
{
SoSeparator *sepDatum = new SoSeparator();
sepDatum->addChild(new SoCoordinate3());
SoLineSet *lineSet = new SoLineSet;
sepDatum->addChild(lineSet);
sep->addChild(sepDatum);
// Add the datum text
sep->addChild(new SoTransform());
// add font for the datum text
SoFont *font = new SoFont();
font->size = 8.f;
font->name = "FreeSans:bold, Helvetica, Arial, FreeSans:bold";
sep->addChild(font);
SoDatumLabel *text = new SoDatumLabel();
//text->justification = SoDatumLabel::CENTER;
text->string = "";
text->textColor = ConstrDimColor;
SoAnnotation *anno = new SoAnnotation();
anno->renderCaching = SoSeparator::OFF;
anno->addChild(text);
sep->addChild(text);
edit->constrGroup->addChild(anno);
edit->vConstrType.push_back((*it)->Type);
continue; // jump to next constraint
}
break;
case Horizontal:
case Vertical:
{
sep->addChild(Material);
sep->addChild(new SoZoomTranslation()); // 1.
sep->addChild(new SoImage()); // 2. constraint icon
@ -2632,6 +2472,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
case Equal:
{
// Add new nodes to Constraint Seperator
sep->addChild(Material);
sep->addChild(new SoZoomTranslation()); // 1.
sep->addChild(new SoImage()); // 2. first constraint icon
sep->addChild(new SoZoomTranslation()); // 3.
@ -2645,6 +2486,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
case Tangent:
{
// Add new nodes to Constraint Seperator
sep->addChild(Material);
sep->addChild(new SoZoomTranslation()); // 1.
sep->addChild(new SoImage()); // 2. constraint icon
@ -2667,6 +2509,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
sepArrows->addChild(new SoCoordinate3());
SoLineSet *lineSet = new SoLineSet;
sepArrows->addChild(lineSet);
sep->addChild(Material);
sep->addChild(sepArrows); // 1.
// Add new nodes to Constraint Seperator
@ -2976,11 +2819,6 @@ void ViewProviderSketch::createEditInventorNodes(void)
MtlBind->value = SoMaterialBinding::OVERALL ;
edit->EditRoot->addChild(MtlBind);
// add font for the text shown constraints
font = new SoFont();
font->size = 8.0;
edit->EditRoot->addChild(font);
// use small line width for the Constraints
DrawStyle = new SoDrawStyle;
DrawStyle->lineWidth = 1;