Custom entities have grip points that appear when the user selects an entity object with a pointing device. The subGetGripPoints() function must fill in the OdGePoint3dArray array of grip points that have been defined for a custom entity. The subMoveGripPointsAt() function performs the entity modifications that result from a grip edit.
virtual OdResult OdDbEntity::subGetGripPoints( OdGePoint3dArray& gripPoints ) const;
virtual OdResult OdDbEntity::subMoveGripPointsAt( const OdGePoint3dArray& gripPoints, const OdIntArray& indices ) const;
The entity defines its grip points and how to interpret the user-supplied action. To edit a custom entity using grips, you must override the subGetGripPoints() and subMoveGripPointsAt() functions. Grip points are added to a special array using the subGetGripPoints function, with each point indicating the order in which it was added beginning with zero (the first point = 0, second point = 1, third point = 2, and so on). Additional points in the array are realized by the append() function of the Array object.
For example, the smiley entity implements the following:
OdResult AsdkSmiley::subGetGripPoints(OdGePoint3dArray& gripPoints) const
{
assertReadEnabled();
// indices
// Grip points to face
OdGePoint3d center( center() );
OdGeVector3d xoff( radius(), 0, 0 ),
yoff( 0, radius(), 0 );
gripPoints.append( center ); // 0
gripPoints.append( center + xoff ); // 1
gripPoints.append( center + yoff ); // 2
gripPoints.append( center - xoff ); // 3
gripPoints.append( center - yoff ); // 4
// Grip points to mouth
gripPoints.append( mouthLeft() ); // 5
gripPoints.append( mouthRight() ); // 6
gripPoints.append( mouthBottom() ); // 7
gripPoints.append( OdGeLineSeg3d(mouthLeft(),mouthRight()).midPoint() ); // 8
// Grip points to eye
xoff.x = yoff.y = meyesize;
// Left eye
center = leftEyeCenter();
gripPoints.append( center ); // 9
gripPoints.append( center + xoff ); // 10
gripPoints.append( center + yoff ); // 11
gripPoints.append( center - xoff ); // 12
gripPoints.append( center - yoff ); // 13
// Right eye
center = rightEyeCenter();
gripPoints.append( center ); // 14
gripPoints.append( center + xoff ); // 15
gripPoints.append( center + yoff ); // 16
gripPoints.append( center - xoff ); // 17
gripPoints.append( center - yoff ); // 18
return eOk;
}
The subMoveGripPointsAt function is used to modify the points of the array. Grip editing in stretch mode allows you to stretch an object by moving selected grips to new locations. The custom object calls the subMoveGripPointsAt() function when the user is in stretch mode. For certain entities, however, some grips move the object rather than stretching it. These grips include grip points of text objects, blocks, midpoints of lines, centers of circles, centers of ellipses, and point objects. In these cases, the subMoveGripPointsAt() function calls the transformBy() function. The subMoveGripPointsAt() function is used to invoke the transformBy() function. If the subMoveGripPointsAt() function is not overridden in the custom entity, the transformBy() function is called.
The subMoveGripPointsAt() function uses a switch operator to check which grip point is being edited. The first function parameter indicates the array of grip points that was created using the subGetGripPoints() function. The second function parameter indicates the array of grip indices that the user edited in stretch mode. Indices of points that have changed position are located in this array. The new position of grip points is stored in the grip points array. You can select a single grip point, but generally you may want to select multiple grip points. The following example illustrates selecting multiple grip points.
OdResult AsdkSmiley::subMoveGripPointsAt(const OdGePoint3dArray& gripPoints, const OdIntArray& indices)
{
assertWriteEnabled();
int idx, count = indices.length();
OdGePoint3d idxpoint;
for( int i = 0; i < count ; i++ ) // A few grip points can be selected concurrently
{
idx = indices[i];
idxpoint = gripPoints[idx];
if( idx == 0 ) // Move the smiley center
{
setCenter( idxpoint );
}
else if( idx >= 1 && idx <= 4 ) // Stretch the smiley radius
{
scaleRadius( idxpoint.distanceTo( center() ));
}
else if( idx == 5 ) // Stretch the left edge of mouth
{
setMouth( idxpoint, mouthBottom(), mouthRight() );
ensureRadiusMouth();
}
else if( idx == 6 ) // Stretch the right edge of mouth
{
setMouth( mouthLeft(), mouthBottom(), idxpoint );
ensureRadiusMouth();
}
else if( idx == 7 ) // Stretch the bottom edge of mouth
{
setMouth( mouthLeft(), idxpoint, mouthRight() );
ensureRadiusMouth();
}
else if( idx == 8 ) // Move the mouth
{
moveMouthToPoint( idxpoint );
ensureRadiusMouth();
}
else if( idx == 9 || idx == 14 ) // Move the center of eyes
{
setEyesApart( (idxpoint.x - center().x) * 2 ); // Apart >= 2*eyeSize
if( eyesApart() < 2 * eyeSize() ) setEyesApart( 2 * eyeSize() );
setEyesHeight( idxpoint.y - center().y ); // Height >= eyeSize
if( eyesHeight() < eyeSize() ) setEyesHeight( eyeSize() );
ensureRadiusEyes();
}
else if((idx >= 10 && idx <= 13) ||
(idx >= 15 && idx <= 18)) // Stretch the radius of eyes
{
setEyeSize( idxpoint.distanceTo( (idx < 14) ? leftEyeCenter() : rightEyeCenter() ) );
if ( 2 * eyeSize() > eyesApart() ) setEyeSize( eyesApart() / 2 );
ensureRadiusEyes();
};
}
return eOk;
}
void AsdkSmiley::moveMouthToPoint(const OdGePoint3d point)
{
OdGePoint3d middle( OdGeLineSeg3d(mouthLeft(), mouthRight()).midPoint() );
OdGeVector3d offset( point.x - middle.x, point.y - middle.y, point.z - middle.z );
setMouth( mouthLeft() + offset, mouthBottom() + offset, mouthRight() + offset );
}
void AsdkSmiley::ensureRadiusMouth()
{
double d;
OdGePoint3d center( center() );
if( (d = center.distanceTo( mouthLeft() )) > radius() / 1.1) setRadius( 1.1 * d );
if( (d = center.distanceTo( mouthRight() )) > radius() / 1.1) setRadius( 1.1 * d );
if( (d = center.distanceTo( mouthBottom() )) > radius() / 1.1) setRadius( 1.1 * d );
}
void AsdkSmiley::ensureRadiusEyes()
{
double d = center().distanceTo(leftEyeCenter()) + eyeSize();
if (d > radius() / 1.1) setRadius( 1.1 * d );
}
Implementing Snap Point Functions
Copyright © 2002 – 2021. Open Design Alliance. All rights reserved.
|