void Additional_Class::Get_PolyLine_Point( AcDbObjectId PolyLineId,AcGePoint3dArray &PointArray )
{
	AcDbEntity *pEnt_Temp = NULL;
	Acad::ErrorStatus es = acdbOpenAcDbEntity(pEnt_Temp, PolyLineId, AcDb::kForRead);
	if (es != Acad::eOk)
	{
		acutPrintf(_T("\nOPEN POLYLINE ERROR"));
		return;
	}
	if (!pEnt_Temp->isKindOf(AcDbPolyline::desc()))
	{
		acutPrintf(_T("\nENTITY IS NOT POLYLINE"));
		return;
	}
	AcDbPolyline *pPolyLine = AcDbPolyline::cast(pEnt_Temp);
	int num = pPolyLine->numVerts();
	AcGePoint3d Start_temp_PT,End_temp_PT;
	for (int index=0; index<num; index++)
	{
		if (pPolyLine->segType(index) == AcDbPolyline::kLine)
		{
			AcGeLineSeg3d tempLine;
			pPolyLine->getLineSegAt(index,tempLine);
			Start_temp_PT = tempLine.startPoint();
			End_temp_PT = tempLine.endPoint();
			PointArray.append(Start_temp_PT);
			PointArray.append(End_temp_PT);
		}
		else if (pPolyLine->segType(index) == AcDbPolyline::kArc)
		{
			AcGeCircArc2d tempArc;
			pPolyLine->getArcSegAt(index,tempArc);
			Start_temp_PT.set(tempArc.startPoint().x,tempArc.startPoint().y,0);
			End_temp_PT.set(tempArc.endPoint().x,tempArc.endPoint().y,0);
			PointArray.append(Start_temp_PT);
			PointArray.append(End_temp_PT);
		}
	}
	pEnt_Temp->close();
	AcGeIntArray IndexArray;
	for (int i=1; i<PointArray.length();i++)
	{
		if (PointArray[i] == PointArray[i-1])
		{
			IndexArray.append(i);
			PointArray.remove(PointArray[i]);
		}
	}
}
void Additional_Class::Get_RectangleLW( AcDbPolyline *PolyLineEntity, double &Length, double &Width )
{
	double temp[2];
	if (PolyLineIfRectangle(PolyLineEntity) == false)
	{
		acutPrintf(_T("Bom Error 1001\n"));// 不是矩形
		return;
	}
	int Num = Get_NumPolyLine(PolyLineEntity);
	for (int i = 0; i<2; i++)
	{
		AcGeLineSeg3d tempLine;
		PolyLineEntity->getLineSegAt(i,tempLine);
		temp[i] = tempLine.length();
	}
	Length = temp[0];
	Width = temp[1];
}
bool Additional_Class::PolyLineIfRectangle( AcDbPolyline *PolyLineEntity )
{
	AcGePoint3dArray tempPt_List;
	AcGePoint3d Start_temp_PT,End_temp_PT;
	if (PolyLineEntity->isClosed())
	{
		int Num = Get_NumPolyLine(PolyLineEntity);
		if (Num == 4)
		{
			for (int i = 0; i<Num; i++)
			{
				if (PolyLineEntity->segType(i) == AcDbPolyline::kLine);
				{
					AcGeLineSeg3d tempLine;
					PolyLineEntity->getLineSegAt(i,tempLine);
					Start_temp_PT = tempLine.startPoint();
					End_temp_PT = tempLine.endPoint();
					tempPt_List.append(Start_temp_PT);
					tempPt_List.append(End_temp_PT);
				}
				if (PolyLineEntity->segType(i) == AcDbPolyline::kArc)
				{
					return false;
				}
			}
			for (int i=2; i<8; i=i+2)
			{
				AcGeVector3d v1,v2;
				v1 = tempPt_List[i-1] - tempPt_List[i-2];
				v2 = tempPt_List[i+1] - tempPt_List[i];
				if (v1.isPerpendicularTo(v2)==Adesk::kFalse )
				{
					return false;
				}
			}
			return true;
		}
		return false;
	}
	return false;
}
void Additional_Class::Get_PolyLine_Length( AcDbObjectId PolyLineId, AcGeDoubleArray &LengthArray )
{
	double PI=3.1415926535897932384626433832795;
	AcDbEntity *pEnt_Temp = NULL;
	Acad::ErrorStatus es = acdbOpenAcDbEntity(pEnt_Temp, PolyLineId, AcDb::kForRead);
	if (es != Acad::eOk)
	{
		acutPrintf(_T("\nOPEN POLYLINE ERROR"));
		return;
	}
	if (!pEnt_Temp->isKindOf(AcDbPolyline::desc()))
	{
		acutPrintf(_T("\nENTITY NOT POLYLINE"));
		return;
	}
	AcDbPolyline *pPolyLine = AcDbPolyline::cast(pEnt_Temp);
	int num = pPolyLine->numVerts();
	for (int index=0; index<num; index++)
	{
		if (pPolyLine->segType(index) == AcDbPolyline::kLine)
		{
			AcGeLineSeg3d tempLine;
			pPolyLine->getLineSegAt(index,tempLine);
			double LineLength = tempLine.length();
			LengthArray.append(LineLength);
		}
		else if (pPolyLine->segType(index) == AcDbPolyline::kArc)
		{
			AcGeCircArc2d tempArc;
			pPolyLine->getArcSegAt(index,tempArc);
			double StartAngle = tempArc.startAng();
			double EndAngle = tempArc.endAng();
			double Angle = EndAngle-StartAngle;
			//Angle = (180/PI)*Angle;
			double Radius = tempArc.radius();
			double ArcLength = Radius*Angle;
			LengthArray.append(ArcLength);
		}
	}
	LengthArray.insertAt(0,0);
}
	virtual Acad::ErrorStatus   getOsnapInfo(
		AcDbEntity*			pickedObject,
		Adesk::GsMarker		gsSelectionMark,
		const AcGePoint3d&		pickPoint,
		const AcGePoint3d&		lastPoint,
		const AcGeMatrix3d&	viewXform,
		AcArray<AcGePoint3d>&	snapPoints,
		AcArray<int>&			geomIdsForPts,
		AcArray<AcGeCurve3d*>& snapCurves,
		AcArray<int>&			geomIdsForLines)
	{
		// Specialised implementation for AcDbPolylines:
		//  Parametrisation of AcDbPolylines is different: each whole numbered paramater appears
		//  at a vertex, so we cannot simply divide by three to get the correct parameter.

		// Protocol Extension insures that the following assertion is always
		// true, but check in non-prod versions just to be safe.
		assert( pickedObject->isKindOf( AcDbPolyline::desc() ));

		// but in production, a hard cast is fastest
		AcDbPolyline *pPline = (AcDbPolyline*)pickedObject;

		Acad::ErrorStatus es;

		if ( bSnapToSegments )
		{
			// Snap to a third of each of the segments
			unsigned int numSegs = pPline->numVerts() - 1;
			AcGeLineSeg3d segLn;
			AcGeCircArc3d segArc;
			double startParam, endParam, newParam, dist;
			AcGePoint3d pt;

			for ( unsigned int idx = 0; idx < numSegs; idx++ )
			{
				switch( pPline->segType( idx ))
				{
				case AcDbPolyline::kLine:
					es=pPline->getLineSegAt( idx, segLn );
					startParam = segLn.paramOf( segLn.startPoint() );
					endParam = segLn.paramOf( segLn.endPoint() );
					snapPoints.append(segLn.evalPoint( startParam + ((endParam - startParam) / 3 )));
					snapPoints.append(segLn.evalPoint( startParam + ((endParam - startParam) * 2 / 3 )));
					break;
				case AcDbPolyline::kArc:
					es=pPline->getArcSegAt( idx, segArc );
					startParam = segArc.paramOf( segArc.startPoint() );
					endParam = segArc.paramOf( segArc.endPoint() );
					dist = segArc.length( startParam, endParam );
					newParam = segArc.paramAtLength( startParam, dist / 3 );
					snapPoints.append( segArc.evalPoint( newParam ));
					newParam = segArc.paramAtLength( startParam, dist * 2 / 3 );
					snapPoints.append( segArc.evalPoint( newParam ));
					break;
				default:
					break;
				}
			}
		}
		else {
			double endParam;
			AcGePoint3d pt;
			double dist;

			es=pPline->getEndParam( endParam );
			es=pPline->getDistAtParam( endParam, dist );
			es=pPline->getPointAtDist( dist / 3, pt );
			assert(Acad::eOk==es);
			snapPoints.append( pt );
			es=pPline->getPointAtDist( dist * 2 / 3, pt );
			assert(Acad::eOk==es);
			snapPoints.append( pt );
			if ( pPline->isClosed() )
			{
				es=pPline->getStartPoint( pt );
				snapPoints.append( pt );
			}
		}
		return Acad::eOk;
	}
	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;
}