Sketcher: Make symmetric constraint more interactable
This commit is contained in:
@@ -446,19 +446,31 @@ private:
|
||||
|
||||
std::vector<SbVec3f> computeSymmetricBBox() const
|
||||
{
|
||||
// Get the points stored in the pnt field
|
||||
// get the points stored in the pnt field
|
||||
const SbVec3f *points = label->pnts.getValues(0);
|
||||
if (label->pnts.getNum() < 2) {
|
||||
return {};
|
||||
}
|
||||
|
||||
SbVec3f p1 = points[0];
|
||||
SbVec3f p2 = points[1];
|
||||
// use shared geometry calculation
|
||||
SoDatumLabel::SymmetricGeometry geom = label->calculateSymmetricGeometry(points);
|
||||
|
||||
// Finds the mins and maxes
|
||||
// include all visual elements in bounding box
|
||||
std::vector<SbVec3f> corners;
|
||||
corners.push_back(p1);
|
||||
corners.push_back(p2);
|
||||
|
||||
// main points (existing)
|
||||
corners.push_back(geom.p1);
|
||||
corners.push_back(geom.p2);
|
||||
|
||||
// first arrow triangle points
|
||||
corners.push_back(geom.ar0); // arrow tip
|
||||
corners.push_back(geom.ar1); // arrow base point 1
|
||||
corners.push_back(geom.ar2); // arrow base point 2
|
||||
|
||||
// second arrow triangle points
|
||||
corners.push_back(geom.ar3); // arrow tip
|
||||
corners.push_back(geom.ar4); // arrow base point 1
|
||||
corners.push_back(geom.ar5); // arrow base point 2
|
||||
|
||||
return corners;
|
||||
}
|
||||
@@ -904,49 +916,37 @@ void SoDatumLabel::generateAnglePrimitives(SoAction * action, const SbVec3f& p0)
|
||||
|
||||
void SoDatumLabel::generateSymmetricPrimitives(SoAction * action, const SbVec3f& p1, const SbVec3f& p2)
|
||||
{
|
||||
SbVec3f dir = (p2-p1);
|
||||
dir.normalize();
|
||||
SbVec3f normal (-dir[1],dir[0],0);
|
||||
// use shared geometry calculation
|
||||
SbVec3f points[2] = {p1, p2};
|
||||
SymmetricGeometry geom = calculateSymmetricGeometry(points);
|
||||
|
||||
float margin = this->imgHeight / 4.0F;
|
||||
// generate selectable primitives for lines
|
||||
float lineWidth = geom.margin * 0.8f;
|
||||
|
||||
// Calculate coordinates for the first arrow
|
||||
SbVec3f ar0 = p1 + dir * 5 * margin ;
|
||||
SbVec3f ar1 = ar0 - dir * 0.866F * 2 * margin; // Base Point of Arrow
|
||||
SbVec3f ar2 = ar1 + normal * margin; // Triangular corners
|
||||
ar1 -= normal * margin;
|
||||
|
||||
// Calculate coordinates for the second arrow
|
||||
SbVec3f ar3 = p2 - dir * 5 * margin ;
|
||||
SbVec3f ar4 = ar3 + dir * 0.866F * 2 * margin; // Base Point of 2nd Arrow
|
||||
|
||||
SbVec3f ar5 = ar4 + normal * margin; // Triangular corners
|
||||
ar4 -= normal * margin;
|
||||
// lines from endpoints to arrow tips
|
||||
generateLineSelectionPrimitive(action, geom.p1, geom.ar0, lineWidth);
|
||||
generateLineSelectionPrimitive(action, geom.p2, geom.ar3, lineWidth);
|
||||
|
||||
// generate selectable primitives for arrow heads as triangles
|
||||
SoPrimitiveVertex pv;
|
||||
pv.setNormal(SbVec3f(0.F, 0.F, 1.F));
|
||||
|
||||
this->beginShape(action, TRIANGLES);
|
||||
|
||||
pv.setNormal( SbVec3f(0.F, 0.F, 1.F) );
|
||||
|
||||
// Set coordinates
|
||||
pv.setPoint( ar0 );
|
||||
// first arrow
|
||||
pv.setPoint(geom.ar0);
|
||||
shapeVertex(&pv);
|
||||
pv.setPoint(geom.ar1);
|
||||
shapeVertex(&pv);
|
||||
pv.setPoint(geom.ar2);
|
||||
shapeVertex(&pv);
|
||||
|
||||
pv.setPoint( ar1 );
|
||||
// second arrow
|
||||
pv.setPoint(geom.ar3);
|
||||
shapeVertex(&pv);
|
||||
|
||||
pv.setPoint( ar2 );
|
||||
pv.setPoint(geom.ar4);
|
||||
shapeVertex(&pv);
|
||||
|
||||
// Set coordinates
|
||||
pv.setPoint( ar3 );
|
||||
shapeVertex(&pv);
|
||||
|
||||
pv.setPoint( ar4 );
|
||||
shapeVertex(&pv);
|
||||
|
||||
pv.setPoint( ar5 );
|
||||
pv.setPoint(geom.ar5);
|
||||
shapeVertex(&pv);
|
||||
|
||||
this->endShape();
|
||||
@@ -1340,43 +1340,27 @@ void SoDatumLabel::drawAngle(const SbVec3f* points, float& angle, SbVec3f& textO
|
||||
|
||||
void SoDatumLabel::drawSymmetric(const SbVec3f* points)
|
||||
{
|
||||
SbVec3f p1 = points[0];
|
||||
SbVec3f p2 = points[1];
|
||||
|
||||
SbVec3f dir = (p2-p1);
|
||||
dir.normalize();
|
||||
SbVec3f normal (-dir[1],dir[0],0);
|
||||
|
||||
float margin = this->imgHeight / 4.0F;
|
||||
|
||||
// Calculate coordinates for the first arrow
|
||||
SbVec3f ar0 = p1 + dir * 4 * margin; // Tip of Arrow
|
||||
SbVec3f ar1 = ar0 - dir * 0.866F * 2 * margin;
|
||||
SbVec3f ar2 = ar1 + normal * margin;
|
||||
ar1 -= normal * margin;
|
||||
// use shared geometry calculation
|
||||
SymmetricGeometry geom = calculateSymmetricGeometry(points);
|
||||
|
||||
// draw first arrow
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(p1[0], p1[1], ZCONSTR);
|
||||
glVertex3f(ar0[0], ar0[1], ZCONSTR);
|
||||
glVertex3f(ar0[0], ar0[1], ZCONSTR);
|
||||
glVertex3f(ar1[0], ar1[1], ZCONSTR);
|
||||
glVertex3f(ar0[0], ar0[1], ZCONSTR);
|
||||
glVertex3f(ar2[0], ar2[1], ZCONSTR);
|
||||
glVertex3f(geom.p1[0], geom.p1[1], ZCONSTR);
|
||||
glVertex3f(geom.ar0[0], geom.ar0[1], ZCONSTR);
|
||||
glVertex3f(geom.ar0[0], geom.ar0[1], ZCONSTR);
|
||||
glVertex3f(geom.ar1[0], geom.ar1[1], ZCONSTR);
|
||||
glVertex3f(geom.ar0[0], geom.ar0[1], ZCONSTR);
|
||||
glVertex3f(geom.ar2[0], geom.ar2[1], ZCONSTR);
|
||||
glEnd();
|
||||
|
||||
// Calculate coordinates for the second arrow
|
||||
SbVec3f ar3 = p2 - dir * 4 * margin; // Tip of 2nd Arrow
|
||||
SbVec3f ar4 = ar3 + dir * 0.866F * 2 * margin;
|
||||
SbVec3f ar5 = ar4 + normal * margin;
|
||||
ar4 -= normal * margin;
|
||||
|
||||
// draw second arrow
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(p2[0], p2[1], ZCONSTR);
|
||||
glVertex3f(ar3[0], ar3[1], ZCONSTR);
|
||||
glVertex3f(ar3[0], ar3[1], ZCONSTR);
|
||||
glVertex3f(ar4[0], ar4[1], ZCONSTR);
|
||||
glVertex3f(ar3[0], ar3[1], ZCONSTR);
|
||||
glVertex3f(ar5[0], ar5[1], ZCONSTR);
|
||||
glVertex3f(geom.p2[0], geom.p2[1], ZCONSTR);
|
||||
glVertex3f(geom.ar3[0], geom.ar3[1], ZCONSTR);
|
||||
glVertex3f(geom.ar3[0], geom.ar3[1], ZCONSTR);
|
||||
glVertex3f(geom.ar4[0], geom.ar4[1], ZCONSTR);
|
||||
glVertex3f(geom.ar3[0], geom.ar3[1], ZCONSTR);
|
||||
glVertex3f(geom.ar5[0], geom.ar5[1], ZCONSTR);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -1793,6 +1777,34 @@ SoDatumLabel::AngleGeometry SoDatumLabel::calculateAngleGeometry(const SbVec3f*
|
||||
return geom;
|
||||
}
|
||||
|
||||
SoDatumLabel::SymmetricGeometry SoDatumLabel::calculateSymmetricGeometry(const SbVec3f* points) const
|
||||
{
|
||||
SymmetricGeometry geom;
|
||||
|
||||
geom.p1 = points[0];
|
||||
geom.p2 = points[1];
|
||||
|
||||
geom.dir = (geom.p2 - geom.p1);
|
||||
geom.dir.normalize();
|
||||
geom.normal = SbVec3f(-geom.dir[1], geom.dir[0], 0);
|
||||
|
||||
geom.margin = this->imgHeight / 4.0F;
|
||||
|
||||
// calculate coordinates for the first arrow
|
||||
geom.ar0 = geom.p1 + geom.dir * 4 * geom.margin; // tip of arrow
|
||||
geom.ar1 = geom.ar0 - geom.dir * 0.866F * 2 * geom.margin;
|
||||
geom.ar2 = geom.ar1 + geom.normal * geom.margin;
|
||||
geom.ar1 -= geom.normal * geom.margin;
|
||||
|
||||
// calculate coordinates for the second arrow
|
||||
geom.ar3 = geom.p2 - geom.dir * 4 * geom.margin; // tip of 2nd arrow
|
||||
geom.ar4 = geom.ar3 + geom.dir * 0.866F * 2 * geom.margin;
|
||||
geom.ar5 = geom.ar4 + geom.normal * geom.margin;
|
||||
geom.ar4 -= geom.normal * geom.margin;
|
||||
|
||||
return geom;
|
||||
}
|
||||
|
||||
void SoDatumLabel::generateLineSelectionPrimitive(SoAction* action, const SbVec3f& start, const SbVec3f& end, float width)
|
||||
{
|
||||
// create a thicker line used for selection
|
||||
|
||||
@@ -151,6 +151,14 @@ private:
|
||||
float endLineLength12, endLineLength22; // extension line lengths (other side)
|
||||
};
|
||||
|
||||
struct SymmetricGeometry {
|
||||
SbVec3f p1, p2; // main points
|
||||
SbVec3f dir, normal; // direction and normal vectors
|
||||
SbVec3f ar0, ar1, ar2; // first arrow triangle points (tip, base1, base2)
|
||||
SbVec3f ar3, ar4, ar5; // second arrow triangle points (tip, base1, base2)
|
||||
float margin; // margin for calculations
|
||||
};
|
||||
|
||||
float getScaleFactor(SoState*) const;
|
||||
void generateDistancePrimitives(SoAction * action, const SbVec3f&, const SbVec3f&);
|
||||
void generateDiameterPrimitives(SoAction * action, const SbVec3f&, const SbVec3f&);
|
||||
@@ -166,6 +174,7 @@ private:
|
||||
DistanceGeometry calculateDistanceGeometry(const SbVec3f* points, float scale, int srch) const;
|
||||
DiameterGeometry calculateDiameterGeometry(const SbVec3f* points) const;
|
||||
AngleGeometry calculateAngleGeometry(const SbVec3f* points) const;
|
||||
SymmetricGeometry calculateSymmetricGeometry(const SbVec3f* points) const;
|
||||
void generateLineSelectionPrimitive(SoAction* action, const SbVec3f& start, const SbVec3f& end, float width);
|
||||
void generateArcSelectionPrimitive(SoAction* action, const SbVec3f& center, float radius, float startAngle, float endAngle, float width);
|
||||
void generateArrowSelectionPrimitive(SoAction* action, const SbVec3f& base, const SbVec3f& dir, float width, float length);
|
||||
|
||||
Reference in New Issue
Block a user