📄 asdksmiley.cpp
字号:
//
// (C) Copyright 2000 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
//
// AsdkSmiley custom object.
#include "StdAfx.h"
#include "StdArx.h"
#include "dbproxy.h"
#include "geassign.h"
#include "acgi.h"
#include <objbase.h>
#define VERSION_ASDKSMILEY 1
//{{AFX_ARX_MACRO
ACRX_DXF_DEFINE_MEMBERS(AsdkSmiley, AcDbEntity,
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
AcDbProxyEntity::kTransformAllowed ||
AcDbProxyEntity::kColorChangeAllowed ||
AcDbProxyEntity::kLayerChangeAllowed,
ASDKSMILEY, AsdkSmileyDb|Product: ObjectDBX Enabler for Smiley Entity|Company: Autodesk Developer Consulting Group|Website: www.autodesk.com/adn/devhelp
);
//}}AFX_ARX_MACRO
bool AsdkSmiley::s_bHasClsid;
CLSID AsdkSmiley::s_clsid;
const double kPi = 3.14159;
const char kClassName[] = "AsdkSmiley";
const double kCurrentVersionNumber = 1.0;
MAKE_ACDBOPENOBJECT_FUNCTION( AsdkSmiley );
AsdkSmiley::AsdkSmiley()
{
setNormal( AcGeVector3d( 0,0,1 ));
setCenter( AcGePoint3d( 0,0,0 ));
setRadius( 1.0 );
double h = 0.4,
d = 0.9,
s = 0.15,
xstart = 0.9 * sin( 1.25 * kPi ),
ystart = 0.9 * cos( 1.25 * kPi ),
xend = 0.9 * cos( 1.75 * kPi ),
yend = 0.9 * sin( 1.75 * kPi );
setEyesApart( d );
setEyesHeight( h );
setEyeSize( s );
AcGeVector3d vecstart( xstart, ystart, 0 ),
vecend( xend, yend, 0 ),
vecbottom( 0, -1.0, 0 );
AcGePoint3d mouthcen( center() );
mouthcen[Y] += 0.4;
setMouth( mouthcen + vecstart, mouthcen + vecbottom, mouthcen + vecend );
setColorIndex( 2 );
}
AsdkSmiley::~AsdkSmiley()
{
}
// initialise the static member corresponding to the CLSID
void
AsdkSmiley::initCLSID()
{
s_bHasClsid = SUCCEEDED(CLSIDFromProgID(L"SmileyDb.Entity",&s_clsid));
}
// return the CLSID for OPM usage
Acad::ErrorStatus
AsdkSmiley::getClassID(CLSID* pClsid) const
{
assertReadEnabled();
if ( s_bHasClsid )
{
*pClsid = s_clsid;
return Acad::eOk;
}
else
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus AsdkSmiley::setColor( const AcCmColor& color, Adesk::Boolean doSubents )
{
assertWriteEnabled();
return AcDbEntity::setColor(color, doSubents);
}
void AsdkSmiley::ensureRadius()
{
AcGeVector2d vec( meyesapart / 2, meyesheight );
if (( vec.length() + 1.2 * meyesize ) > radius() )
setRadius( vec.length() + 1.2 * meyesize);
AcGePoint3d center( center() ),
smilecen( mouthCenter() ),
startpt( mouthLeft() ),
endpt( mouthRight() ),
botpt( mouthBottom() );
AcGeVector3d vecstart = startpt - smilecen;
if ( center.distanceTo( startpt ) > radius() / 1.1 )
setRadius( 1.1 * center.distanceTo( startpt ));
if ( center.distanceTo( endpt ) > radius() / 1.1 )
setRadius( 1.1 * center.distanceTo( endpt ));
if ( center.distanceTo( botpt ) > radius() / 1.1 )
setRadius( 1.1 * center.distanceTo( botpt ));
}
Adesk::Boolean
AsdkSmiley::worldDraw(AcGiWorldDraw *wd)
{
assertReadEnabled();
AcGeVector3d offset(0,0,0);
AcGeCircArc3d face = mfacecircle;
// If dragging, don't fill the smiley
//
if( wd->isDragging() ){
wd->subEntityTraits().setColor( colorIndex() );
wd->subEntityTraits().setFillType( kAcGiFillNever );
}
else
wd->subEntityTraits().setFillType( kAcGiFillAlways );
// Give the circle a GS marker of 1
//
wd->subEntityTraits().setSelectionMarker( 1 );
wd->geometry().circle( face.center(), face.radius(), mnormal );
if( !wd->isDragging() )
wd->subEntityTraits().setColor( 250 );
// Give the eyes GS markers of 2 etc.
//
AcGePoint3dArray eyearray;
eyes( eyearray );
for( int i = 0; i < eyearray.length(); i++ ){
wd->subEntityTraits().setSelectionMarker( i + 2 );
wd->geometry().circle( eyearray.at(i) + offset, meyesize, mnormal );
}
AcGePoint3d smilecen( mouthCenter() + offset ),
startpt( mouthLeft() + offset ),
endpt( mouthRight() + offset );
AcGeVector3d startvec = startpt - smilecen,
endvec = endpt - smilecen;
double mouthangle = startvec.angleTo( endvec );
wd->subEntityTraits().setSelectionMarker( eyearray.length() + 2 );
wd->geometry().circularArc( smilecen, mouthRadius(), mnormal, startvec, mouthangle, kAcGiArcChord );
return Adesk::kTrue;
}
Acad::ErrorStatus
AsdkSmiley::dwgInFields(AcDbDwgFiler *filer)
{
assertWriteEnabled();
AcDbEntity::dwgInFields( filer );
// Read version number
double version;
filer->readItem( &version );
if ( version > kCurrentVersionNumber ){
ads_printf( "\nNew version of AsdkSmiley object found (version %.1f found, version %.1f supported): upgrade your Smiley.dbx to enable these objects.", version, kCurrentVersionNumber );
return Acad::eMakeMeProxy;
}
AcGePoint3d center, mouthleftpt, mouthbottompt, mouthrightpt;
double radius;
filer->readItem( ¢er );
filer->readItem( &radius );
setCenter( center );
setRadius( radius );
filer->readItem( &mnormal );
filer->readItem( &meyesapart );
filer->readItem( &meyesheight );
filer->readItem( &meyesize );
filer->readItem( &mouthleftpt );
filer->readItem( &mouthbottompt );
filer->readItem( &mouthrightpt );
setMouth( mouthleftpt, mouthbottompt, mouthrightpt );
return filer->filerStatus();
}
Acad::ErrorStatus
AsdkSmiley::dwgOutFields(AcDbDwgFiler *filer) const
{
assertReadEnabled();
AcDbEntity::dwgOutFields( filer );
// Write version number
filer->writeItem( kCurrentVersionNumber );
filer->writeItem( center() );
filer->writeItem( radius() );
filer->writeItem( mnormal );
filer->writeItem( meyesapart );
filer->writeItem( meyesheight );
filer->writeItem( meyesize );
filer->writeItem( mouthLeft() );
filer->writeItem( mouthBottom() );
filer->writeItem( mouthRight() );
return filer->filerStatus();
}
Acad::ErrorStatus
AsdkSmiley::dxfInFields(AcDbDxfFiler *filer)
{
assertWriteEnabled();
struct resbuf rb;
AcGePoint3d center, mouthleftpt, mouthbottompt, mouthrightpt;
double radius;
Acad::ErrorStatus es = AcDbEntity::dxfInFields( filer );
if( Acad::eOk != es ) {
return es;
}
// Check that we are at the correct subclass data
//
if( !filer->atSubclassData( kClassName )) {
return Acad::eBadDxfSequence;
}
// First piece of data MUST be the version number
if( Acad::eOk != ( es = filer->readItem( &rb ))) {
return es;
}
if ( AcDb::kDxfReal != rb.restype ){
ads_printf( "\nNo version information found in object definition." );
return Acad::eMakeMeProxy;
}
// Check version first
if ( rb.resval.rreal > 1.0 ){
ads_printf( "\nNew version of AsdkSmiley object found (version %.1f): upgrade your Smiley.dbx to enable these objects.", rb.resval.rreal );
return Acad::eMakeMeProxy;
}
// Set the normal's default value in case it's not in the
// DXF information coming in
//
mnormal = AcGeVector3d( 0, 0, 1 ); // set default value:
while( Acad::eOk == es ) {
if( Acad::eOk == ( es = filer->readItem( &rb ))) {
switch( rb.restype ) {
case AcDb::kDxfXCoord:
center.set( rb.resval.rpoint[X],
rb.resval.rpoint[Y],
rb.resval.rpoint[Z]);
setCenter( center );
break;
case AcDb::kDxfReal+1:
radius = rb.resval.rreal;
setRadius( radius );
break;
case AcDb::kDxfNormalX:
mnormal.set( rb.resval.rpoint[X],
rb.resval.rpoint[Y],
rb.resval.rpoint[Z]);
case AcDb::kDxfReal+2:
meyesapart = rb.resval.rreal;
break;
case AcDb::kDxfReal+3:
meyesheight = rb.resval.rreal;
break;
case AcDb::kDxfReal+4:
meyesize = rb.resval.rreal;
break;
case AcDb::kDxfXCoord+1:
mouthleftpt.set( rb.resval.rpoint[X],
rb.resval.rpoint[Y],
rb.resval.rpoint[Z]);
setMouthLeft( mouthleftpt );
break;
case AcDb::kDxfXCoord+2:
mouthbottompt.set( rb.resval.rpoint[X],
rb.resval.rpoint[Y],
rb.resval.rpoint[Z]);
setMouthBottom( mouthbottompt );
break;
case AcDb::kDxfXCoord+3:
mouthrightpt.set( rb.resval.rpoint[X],
rb.resval.rpoint[Y],
rb.resval.rpoint[Z]);
setMouthRight( mouthrightpt );
break;
}
}
}
return filer->filerStatus();
}
Acad::ErrorStatus
AsdkSmiley::dxfOutFields(AcDbDxfFiler *filer) const
{
assertReadEnabled();
AcDbEntity::dxfOutFields( filer );
filer->writeItem( AcDb::kDxfSubclass, kClassName );
// Write version number
filer->writeItem( AcDb::kDxfReal, kCurrentVersionNumber );
filer->writeItem( AcDb::kDxfXCoord, center() );
filer->writeItem( AcDb::kDxfReal+1, radius() );
if( filer->includesDefaultValues()
|| mnormal != AcGeVector3d( 0, 0, 1 ))
{
filer->writeItem( AcDb::kDxfNormalX, mnormal );
}
filer->writeItem( AcDb::kDxfReal+2, meyesapart );
filer->writeItem( AcDb::kDxfReal+3, meyesheight );
filer->writeItem( AcDb::kDxfReal+4, meyesize );
filer->writeItem( AcDb::kDxfXCoord+1, mouthLeft() );
filer->writeItem( AcDb::kDxfXCoord+2, mouthBottom() );
filer->writeItem( AcDb::kDxfXCoord+3, mouthRight() );
return filer->filerStatus();
}
Acad::ErrorStatus
AsdkSmiley::explode(AcDbVoidPtrArray& entities) const
{
assertReadEnabled();
AcDbCircle *pCircle = new AcDbCircle( center(), mnormal, radius() );
entities.append( pCircle );
// Create eyes
//
AcGePoint3dArray eyearray;
eyes( eyearray );
for( int i = 0; i < eyearray.length(); i++ ){
AcDbCircle *pCircle = new AcDbCircle( eyearray.at(i), mnormal, meyesize );
entities.append( pCircle );
}
// Create smile arc
//
AcGePoint3d smilecen( mouthCenter() ),
startpt( mouthLeft() ),
endpt( mouthRight() );
AcGeVector3d normvec( 1, 0, 0 ),
startvec = startpt - smilecen,
endvec = endpt - smilecen;
double startang = 2 * kPi - startvec.angleTo( normvec ),
endang = 2 * kPi - endvec.angleTo( normvec );
AcDbArc *pArc = new AcDbArc( smilecen, mnormal, mouthRadius(), startang, endang );
entities.append( pArc );
// Create smile arc chord
//
AcDbLine *pLine = new AcDbLine( startpt, endpt );
entities.append( pLine );
return Acad::eOk;
}
void
AsdkSmiley::list() const
{
assertReadEnabled();
AcGePoint3d cen( center() );
double rad = radius();
AcDbEntity::list();
acutPrintf(
"%12scenter point, X=%9.16q0 Y=%9.16q0 Z=%9.16q0\n"
"%11s radius %9.16q0\n"
"%7s eye radius %9.16q0\n"
"%7s eye height %9.16q0\n"
"%7s eyes apart %9.16q0\n",
"", cen[X], cen[Y], cen[Z], "",
rad, "", meyesize, "",
meyesheight, "", meyesapart
);
}
Acad::ErrorStatus
AsdkSmiley::getOsnapPoints(
AcDb::OsnapMode osnapMode,
int gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
switch( osnapMode ) {
case AcDb::kOsModeNear:
return osnapNear( pickPoint, snapPoints );
case AcDb::kOsModeCen:
return osnapCen( pickPoint, snapPoints );
case AcDb::kOsModeQuad:
return osnapQuad( pickPoint, snapPoints );
case AcDb::kOsModeMid:
case AcDb::kOsModeEnd:
case AcDb::kOsModeNode:
case AcDb::kOsModeIns:
case AcDb::kOsModePerp:
case AcDb::kOsModeTan:
default:
break;
}
return Acad::eInvalidInput;
}
Acad::ErrorStatus
AsdkSmiley::getGripPoints(
AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapMasks,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
// Grip points to face
//
AcGePoint3d center( center() );
gripPoints.append( center );
AcGeVector3d xoff( radius(), 0, 0 ),
yoff( 0, radius(), 0 );
gripPoints.append( center + xoff );
gripPoints.append( center + yoff );
gripPoints.append( center - xoff );
gripPoints.append( center - yoff );
// Grip points to mouth
//
AcGeLineSeg3d chord( mouthLeft(), mouthRight() );
gripPoints.append( mouthLeft() );
gripPoints.append( mouthRight() );
gripPoints.append( chord.midPoint() );
gripPoints.append( mouthBottom() );
// Grip points to eyes
//
AcGePoint3dArray eyearray;
AcGePoint3d eyecen;
eyes( eyearray );
for( int i = 0; i < eyearray.length(); i++ ){
eyecen = eyearray.at( i );
gripPoints.append( eyecen );
AcGeVector3d xoff( meyesize, 0, 0 ),
yoff( 0, meyesize, 0 );
gripPoints.append( eyecen + xoff );
gripPoints.append( eyecen + yoff );
gripPoints.append( eyecen - xoff );
gripPoints.append( eyecen - yoff );
}
return Acad::eOk;
}
Acad::ErrorStatus
AsdkSmiley::moveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
AcGePoint3dArray eyearray;
AcGePoint3d oldquad, newquad, newmouthcenter, newmouthbottom,
smilecen, startpt, endpt, midpt, newpt;
AcGeVector3d vecstart(0,0,0), vecend(0,0,0), newvec(0,0,0);
eyes( eyearray );
for( int i = 0; i < indices.length(); i++ ) {
int idx = indices[i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -