AcDbIntArray &   geomIds) const
#else
Acad::ErrorStatus PDSphere::getOsnapPoints(
	AcDb::OsnapMode       osnapMode,
	int                   gsSelectionMark,
	const AcGePoint3d&    pickPoint,
	const AcGePoint3d&    lastPoint,
	const AcGeMatrix3d&   viewXform,
	AcGePoint3dArray&     snapPoints,
	AcDbIntArray&         geomIds) const
#endif
{
	assertReadEnabled();

	if(!hasSnap())
		return Acad::eOk;

	if(gsSelectionMark == 0)
		return Acad::eOk;

	AcGeVector3d viewDir(viewXform(Z, 0), viewXform(Z, 1),
		viewXform(Z, 2));

	switch(osnapMode)
	{
	case AcDb::kOsModeEnd:
		break;
	case AcDb::kOsModeMid:
		break;
	case AcDb::kOsModeCen:
		snapPoints.append(m_ptCenter);
		break;
	case AcDb::kOsModeQuad:
		{
			AcGeCubicSplineCurve3d varcur;
			AcGeCubicSplineCurve3d varcurs[7];
			switch(gsSelectionMark)
			{
			case 1:
				varcur = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(1, 0, 0), m_dRadius));
				break;
			case 2:
				varcur = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(1, 1, 0), m_dRadius));
				break;
			case 3:
				varcur = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(0, 1, 0), m_dRadius));
				break;
			case 4:
				varcur = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(-1, 1, 0), m_dRadius));
				break;
			case 5:
				varcur = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(0, 0, 1), m_dRadius));
				break;
			case 6:
				varcur = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter - AcGeVector3d(0, 0, 1) * m_dRadius *  cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0)));
				break;
			case 7:
				varcur = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter + AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0)));
				break;
			//定义球面象限点的捕捉方式
			//added by szw 2009.11.18 : begin
			case 8:
				varcurs[0] = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(1, 0, 0), m_dRadius));
				varcurs[1] = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(1, 1, 0), m_dRadius));
				varcurs[2] = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(0, 1, 0), m_dRadius));
				varcurs[3] = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(-1, 1, 0), m_dRadius));
				varcurs[4] = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter, AcGeVector3d(0, 0, 1), m_dRadius));
				varcurs[5] = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter - AcGeVector3d(0, 0, 1) * m_dRadius *  cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0)));
				varcurs[6] = AcGeCubicSplineCurve3d(AcGeCircArc3d(m_ptCenter + AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0)));
				break;
			default:
				break;
			//added by szw 2009.11.18 : end
			}
			if(gsSelectionMark < 8)
			{
				double fromParam = varcur.startParam();
				double toParam = varcur.endParam();
				double delta = (toParam - fromParam) / 4.0;
				for(int i = 0; i < 4; i++)
					snapPoints.append(varcur.evalPoint(fromParam + i * delta));
			}
			//定义球面象限点的捕捉方式
			//added by szw 2009.11.18 : begin
			else if(gsSelectionMark == 8)
			{
				for(int j = 0; j < 7; ++j)
				{
					double fromParam = varcurs[j].startParam();
					double toParam = varcurs[j].endParam();
					double delta = (toParam - fromParam) / 4.0;
					for(int i = 0; i < 4; i++)
						snapPoints.append(varcurs[j].evalPoint(fromParam + i * delta));
				}
			}
			//added by szw 2009.11.18 : end
		}
		break;
	case AcDb::kOsModeNode:
		break;
	case AcDb::kOsModeIns:
		snapPoints.append(m_ptCenter);
		break;
	case AcDb::kOsModePerp:
		{
			AcGeCircArc3d cir;
			AcGeCircArc3d cirs[7];
			switch(gsSelectionMark)
			{
			case 1:
				cir.set(m_ptCenter, AcGeVector3d(1, 0, 0), m_dRadius);
				break;
			case 2:
				cir.set(m_ptCenter, AcGeVector3d(1, 1, 0), m_dRadius);
				break;
			case 3:
				cir.set(m_ptCenter, AcGeVector3d(0, 1, 0), m_dRadius);
				break;
			case 4:
				cir.set(m_ptCenter, AcGeVector3d(-1, 1, 0), m_dRadius);
				break;
			case 5:
				cir.set(m_ptCenter, AcGeVector3d(0, 0, 1), m_dRadius);
				break;
			case 6:
				cir.set(m_ptCenter - AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius *sin(PI / 4.0));
				break;
			case 7:
				cir.set(m_ptCenter + AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0));
				break;
			//定义球面垂直正交点的捕捉方式
			//added by szw 2009.11.18 : begin
			case 8:
				cirs[0].set(m_ptCenter, AcGeVector3d(1, 0, 0), m_dRadius);
				cirs[1].set(m_ptCenter, AcGeVector3d(1, 1, 0), m_dRadius);
				cirs[2].set(m_ptCenter, AcGeVector3d(0, 1, 0), m_dRadius);
				cirs[3].set(m_ptCenter, AcGeVector3d(-1, 1, 0), m_dRadius);
				cirs[4].set(m_ptCenter, AcGeVector3d(0, 0, 1), m_dRadius);
				cirs[5].set(m_ptCenter - AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius *sin(PI / 4.0));
				cirs[6].set(m_ptCenter + AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0));
				break;
			default:
				break;
			//added by szw 2009.11.18 : end
			}
			if(gsSelectionMark < 8)
			{
				AcGePoint3d pt;
				pt = cir.closestPointTo(lastPoint);
				snapPoints.append(pt);
			}
			//定义球面垂直正交点的捕捉方式
			//added by szw 2009.11.18 : begin
			else if(gsSelectionMark == 8)
			{
				for(int i = 0; i < 7; ++i)
				{
					AcGePoint3d pt;
					pt = cirs[i].closestPointTo(lastPoint);
					snapPoints.append(pt);
				}
			}
			//added by szw 2009.11.18 : end
		}
		break;
	case AcDb::kOsModeTan:
		break;
	case AcDb::kOsModeNear:
		{
			AcGePoint3d pt;
			AcGeCircArc3d cir;
			AcGeCircArc3d cirs[7];
			switch(gsSelectionMark)
			{
			case 1:
				cir.set(m_ptCenter, AcGeVector3d(1, 0, 0), m_dRadius);
				break;
			case 2:
				cir.set(m_ptCenter, AcGeVector3d(1, 1, 0), m_dRadius);
				break;
			case 3:
				cir.set(m_ptCenter, AcGeVector3d(0, 1, 0), m_dRadius);
				break;
			case 4:
				cir.set(m_ptCenter, AcGeVector3d(-1, 1, 0), m_dRadius);
				break;
			case 5:
				cir.set(m_ptCenter, AcGeVector3d(0, 0, 1), m_dRadius);
				break;
			case 6:
				cir.set(m_ptCenter - AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius *sin(PI / 4.0));
				break;
			case 7:
				cir.set(m_ptCenter + AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0));
				break;
			//定义球面垂直正交点的捕捉方式
			//added by szw 2009.11.18 : begin
			case 8:
				cirs[0].set(m_ptCenter, AcGeVector3d(1, 0, 0), m_dRadius);
				cirs[1].set(m_ptCenter, AcGeVector3d(1, 1, 0), m_dRadius);
				cirs[2].set(m_ptCenter, AcGeVector3d(0, 1, 0), m_dRadius);
				cirs[3].set(m_ptCenter, AcGeVector3d(-1, 1, 0), m_dRadius);
				cirs[4].set(m_ptCenter, AcGeVector3d(0, 0, 1), m_dRadius);
				cirs[5].set(m_ptCenter - AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius *sin(PI / 4.0));
				cirs[6].set(m_ptCenter + AcGeVector3d(0, 0, 1) * m_dRadius * cos(PI / 4.0), AcGeVector3d(0, 0, 1), m_dRadius * sin(PI / 4.0));
				break;
			default:
				break;
			//added by szw 2009.11.18 : end
			}
			if(gsSelectionMark < 8)
			{
				pt = cir.projClosestPointTo(pickPoint, viewDir);
				snapPoints.append(pt);
			}
			//定义球面垂直正交点的捕捉方式
			//added by szw 2009.11.18 : begin
			else if(gsSelectionMark == 8)
			{
				for(int i = 0; i < 7; ++i)
				{
					pt = cirs[i].projClosestPointTo(pickPoint, viewDir);
					snapPoints.append(pt);
				}
			}
			//added by szw 2009.11.18 : end
		}
		break;
	default:
		break;
	}

	return Acad::eOk;
}
Acad::ErrorStatus 
rx_makeArc(const AcGePoint3d    pt1, 
           const AcGePoint3d    pt2, 
                 double         bulge,
           const AcGeVector3d   entNorm,
                 AcGeCircArc3d& arc)
{
    Acad::ErrorStatus es = Acad::eOk;

    // The points that are coming in are in ECS. These are actually
    // 2d points, may be with an elevation in the z coord.
    //
    // Therefore, let's create a 2d arc from these values and transform
    // the relevant data of the arc for creating a 3d arc.

    AcGeCircArc2d arc2d;
    AcGePoint2d p1, p2;

    assert(fabs(pt1[Z] - pt2[Z]) < 1.0e-10);

    p1.set(pt1[X], pt1[Y]); p2.set(pt2[X], pt2[Y]);
    arc2d.set(p1, p2, bulge);

    AcGePoint3d center((arc2d.center())[X], (arc2d.center())[Y], pt1[Z]);
    AcGePoint3d startPnt((arc2d.startPoint())[X], 
                         (arc2d.startPoint())[Y], pt1[Z]);
    AcGePoint3d endPnt((arc2d.endPoint())[X], (arc2d.endPoint())[Y], pt1[Z]);

    // If the arc is CW, flip the normal.

    AcGeVector3d norm;

    if (arc2d.startAng() > arc2d.endAng()) {
	norm.set(0, 0, -1);
    } else {
	norm.set(0, 0, 1);
    }

    double incAng = fabs(arc2d.endAng() - arc2d.startAng());

    // Transform all the data to WCS.

    acdbEcs2Wcs(asDblArray(center), asDblArray(center), asDblArray(entNorm), 
							    Adesk::kFalse);
    acdbEcs2Wcs(asDblArray(startPnt), asDblArray(startPnt), asDblArray(entNorm), 
							    Adesk::kFalse);
    acdbEcs2Wcs(asDblArray(endPnt), asDblArray(endPnt), asDblArray(entNorm), 
							    Adesk::kFalse);
    acdbEcs2Wcs(asDblArray(norm), asDblArray(norm), asDblArray(entNorm), 
							    Adesk::kTrue);

    arc.set(center, norm, norm.perpVector(),
	(startPnt - center).length(), 0, incAng);

    return es;
}
	AcDbIntArray &   geomIds) const
#else
Acad::ErrorStatus PDEcone::getOsnapPoints(
	AcDb::OsnapMode       osnapMode,
	int                   gsSelectionMark,
	const AcGePoint3d&    pickPoint,
	const AcGePoint3d&    lastPoint,
	const AcGeMatrix3d&   viewXform,
	AcGePoint3dArray&     snapPoints,
	AcDbIntArray&         geomIds) const
#endif
{
    assertReadEnabled();

    if(!hasSnap())
        return Acad::eOk;

	int gsSelectionMark_int = (int)gsSelectionMark;
    if(gsSelectionMark_int == 0)
        return Acad::eOk;

    AcGePoint3dArray pArray;
    AcGeIntArray stdIdx;
    int actPrecision;
    getVertices(m_dDividPrecision, pArray, stdIdx, actPrecision);
    int actPrecision__1 = actPrecision + 1;
    int stdIdxLen = stdIdx.length();
    int stdIdxLen_1 = stdIdxLen - 1;
    int stdIdxLen____2 = stdIdxLen / 2;

    AcGeVector3d viewDir(viewXform(Z, 0), viewXform(Z, 1),
                         viewXform(Z, 2));
    AcGeVector3d vect = getFaceVect();

    int i;
    switch(osnapMode)
    {
    case AcDb::kOsModeEnd:
        snapPoints.append(m_ptStart);
		snapPoints.append(m_ptEnd);
        for(i = 0; i < stdIdxLen_1; ++i)
        {
            snapPoints.append(pArray[stdIdx[i]]);
            snapPoints.append(pArray[stdIdx[i] + actPrecision__1]);
        }
		break;
    case AcDb::kOsModeMid:
        snapPoints.append(m_ptStart + (m_ptEnd - m_ptStart) / 2.0);
        for(i = 0; i < stdIdxLen_1; ++i)
            snapPoints.append(pArray[stdIdx[i]] + 
                              (pArray[stdIdx[i] + actPrecision__1] - pArray[stdIdx[i]]) / 2.0);
        break;
    case AcDb::kOsModeCen:
	    if(gsSelectionMark_int == 1)
            snapPoints.append(m_ptStart);
        else if(gsSelectionMark_int == 2)
		    snapPoints.append(m_ptEnd);
        else
		    snapPoints.append(m_ptStart + (m_ptEnd - m_ptStart) / 2.0);
		break;
	case AcDb::kOsModeQuad:
	    for(i = 0; i < stdIdxLen____2; i++)
        {
            snapPoints.append(pArray[stdIdx[i * 2]]);
            snapPoints.append(pArray[stdIdx[i * 2] + actPrecision__1]);
	    }
        break;
    case AcDb::kOsModeNode:
		break;
    case AcDb::kOsModeIns:
		snapPoints.append(m_ptStart);
		break;
    case AcDb::kOsModePerp:
		{
            AcGeLine3d line;
            AcGeVector3d vec;
            AcGePoint3d pt;
            if(gsSelectionMark_int == 1)
            {
                AcGeCircArc3d cir(m_ptStart, vect, m_dDiameter1 / 2.0);
                pt = cir.closestPointTo(lastPoint);
                snapPoints.append(pt);
            }
            else if(gsSelectionMark_int == 2)
            {
                AcGeCircArc3d cir(m_ptEnd, vect, m_dDiameter2 / 2.0);
                pt = cir.closestPointTo(lastPoint);
                snapPoints.append(pt);
            }
			//重新定义对象垂直正交点的捕捉方式,同时满足实体模型和线框模型的捕捉 
			//modified by szw 2009.11.18 : begin
            else if(gsSelectionMark_int == 3)
            {
				for(int i = 0; i < stdIdxLen - 1; ++i)
				{
					vec = pArray[stdIdx[i]] - pArray[stdIdx[i] + actPrecision__1];
					line.set(pArray[stdIdx[i]], vec);
					pt = line.closestPointTo(lastPoint);
					snapPoints.append(pt);
				}
            }
			//modified by szw 2009.11.18 : end
        }
		break;
    case AcDb::kOsModeTan:
		break;
    case AcDb::kOsModeNear:
        {
            AcGePoint3d pt;
            AcGeCircArc3d cir;
            //下底面
            if(gsSelectionMark_int == 1)
            {
                cir.set(m_ptStart, vect, m_dDiameter1 / 2.0);
                pt = cir.projClosestPointTo(pickPoint, viewDir);
                snapPoints.append(pt);
            }
            //上底面
            else if(gsSelectionMark_int == 2)
            {
                cir.set(m_ptEnd, vect, m_dDiameter2 / 2.0);
                pt = cir.projClosestPointTo(pickPoint, viewDir);
                snapPoints.append(pt);
            }
            //棱边
			//重新定义对象垂直正交点的捕捉方式,同时满足实体模型和线框模型的捕捉 
			//modified by szw 2009.11.18 : begin
            else if(gsSelectionMark_int == 3)
            {
				AcGeLineSeg3d lnsg;
				AcGePoint3d p1,p2;
				for(int i = 0; i < stdIdxLen - 1; ++i)
				{
					p1 = pArray[stdIdx[i]];
					p2 = pArray[stdIdx[i] + actPrecision__1];
					lnsg.set(p1, p2);
// 					lnsg.set(pArray[stdIdx[i]], pArray[stdIdx[i] + actPrecision__1]);
					pt = lnsg.projClosestPointTo(pickPoint, viewDir);
					snapPoints.append(pt);

				}
            }
			//modified by szw 2009.11.18 : end
        }
        break;
    default:
        break;
    }

  return Acad::eOk;
}