Sketcher, 0000466: improve visualization of constraints
This commit is contained in:
parent
e5953cedac
commit
da7528c5b9
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ public:
|
|||
int Third;
|
||||
PointPos ThirdPos;
|
||||
float LabelDistance;
|
||||
float LabelPosition;
|
||||
};
|
||||
|
||||
} //namespace Sketcher
|
||||
|
|
|
@ -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 ¢er)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user