Acad::ErrorStatus Custom::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, viewXform, snapPoints ); case AcDb::kOsModeEnd: case AcDb::kOsModeMid: case AcDb::kOsModePerp: case AcDb::kOsModeCen: return osnapCenter( pickPoint, snapPoints ); case AcDb::kOsModeQuad: return osnapQuadrant( pickPoint, snapPoints ); case AcDb::kOsModeNode: case AcDb::kOsModeIns: case AcDb::kOsModeTan: default: break; } return Acad::eInvalidInput; } Acad::ErrorStatus Custom::osnapNear( const AcGePoint3d& pickPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints ) const { AcGeVector3d viewDir( viewXform( Z, 0 ), viewXform( Z, 1 ), viewXform( Z, 2 ) ); Acad::ErrorStatus es = Acad::eOk; AcGePoint3d center1, center2, pt; AcGeVector3d normal( 0.0, 0.0, 1.0 ); AcGeVector3d axis = mEndPoint - mStartPoint; axis.normalize(); center1 = mStartPoint + (axis * mRadius1 ); center2 = mEndPoint - (axis * mRadius2 ); AcGeCircArc3d *circle1 = new AcGeCircArc3d( center1, normal, mRadius1 ); AcGeCircArc3d *circle2 = new AcGeCircArc3d( center2, normal, mRadius2 ); if( center1.distanceTo( pickPoint ) < center2.distanceTo( pickPoint ) ) { pt = circle1->projClosestPointTo( pickPoint, viewDir ); } else { pt = circle2->projClosestPointTo( pickPoint, viewDir ); } snapPoints.append( pt ); delete circle1; delete circle2; return es; } Acad::ErrorStatus Custom::osnapCenter( const AcGePoint3d& pickPoint, AcGePoint3dArray& snapPoints ) const { AcGePoint3d center1, center2, pt; AcGeVector3d axis = mEndPoint - mStartPoint; axis.normalize(); center1 = mStartPoint + (axis * mRadius1 ); center2 = mEndPoint - (axis * mRadius2 ); if( center1.distanceTo( pickPoint ) < center2.distanceTo( pickPoint ) ) { snapPoints.append( center1 ); } else { snapPoints.append( center2 ); } return Acad::eOk; } Acad::ErrorStatus Custom::osnapQuadrant( const AcGePoint3d& pickPoint, AcGePoint3dArray& snapPoints ) const { AcGePoint3d center1, center2, pt, q1, q2, q3, q4; AcGeVector3d normal( 0.0, 0.0, 1.0 ); AcGeVector3d ox( 1.0, 0.0, 0.0 ); AcGeVector3d oy( 0.0, 1.0, 0.0 ); AcGeVector3d axis = mEndPoint - mStartPoint; axis.normalize(); center1 = mStartPoint + (axis * mRadius1 ); center2 = mEndPoint - (axis * mRadius2 ); if( center1.distanceTo( pickPoint ) < center2.distanceTo( pickPoint ) ) { q1 = center1 + ( ox * mRadius1 ); q2 = center1 + ( oy * mRadius1 ); q3 = center1 - ( ox * mRadius1 ); q4 = center1 - ( oy * mRadius1 ); if( q1.distanceTo( pickPoint ) < q2.distanceTo( pickPoint ) && q1.distanceTo( pickPoint ) < q4.distanceTo( pickPoint ) ) { pt = q1; } else if( q2.distanceTo( pickPoint ) < q1.distanceTo( pickPoint ) && q2.distanceTo( pickPoint ) < q3.distanceTo( pickPoint ) ) { pt = q2; } else if( q3.distanceTo( pickPoint ) < q2.distanceTo( pickPoint ) && q3.distanceTo( pickPoint ) < q4.distanceTo( pickPoint ) ) { pt = q3; } else { pt = q4; } } else { q1 = center2 + ( ox * mRadius2 ); q2 = center2 + ( oy * mRadius2 ); q3 = center2 - ( ox * mRadius2 ); q4 = center2 - ( oy * mRadius2 ); if( q1.distanceTo( pickPoint ) < q2.distanceTo( pickPoint ) && q1.distanceTo( pickPoint ) < q4.distanceTo( pickPoint ) ) { pt = q1; } else if( q2.distanceTo( pickPoint ) < q1.distanceTo( pickPoint ) && q2.distanceTo( pickPoint ) < q3.distanceTo( pickPoint ) ) { pt = q2; } else if( q3.distanceTo( pickPoint ) < q2.distanceTo( pickPoint ) && q3.distanceTo( pickPoint ) < q4.distanceTo( pickPoint ) ) { pt = q3; } else { pt = q4; } } snapPoints.append( pt ); return Acad::eOk; } static Acad::ErrorStatus intLine( Custom* custom, const AcDbLine* line, AcDb::Intersect intType, const AcGePlane* projPlane, AcGePoint3dArray& points); static Acad::ErrorStatus intLine( Custom* custom, const AcGeLineSeg3d line, AcGePoint3dArray& points); static Acad::ErrorStatus intLine( Custom* custom, const AcGeLineSeg3d line, AcGePoint3dArray& points) { Acad::ErrorStatus es = Acad::eOk; AcGePoint3d startPoint, endPoint, center1, center2, pt1, pt2; startPoint = custom->getStartPoint(); endPoint = custom->getEndPoint(); AcGeVector3d normal( 0.0, 0.0, 1.0 ); AcGeVector3d axis = endPoint - startPoint; axis.normalize(); double radius1 = custom->getRadius1(); double radius2 = custom->getRadius2(); int noOfPoints; center1 = startPoint + (axis * radius1 ); center2 = endPoint - (axis * radius2 ); AcGeCircArc3d *circle1 = new AcGeCircArc3d( center1, normal, radius1 ); AcGeCircArc3d *circle2 = new AcGeCircArc3d( center2, normal, radius2 ); if( circle1->intersectWith( line, noOfPoints, pt1, pt2 ) ) { points.append( pt1 ); points.append( pt2 ); } else if( circle2->intersectWith( line, noOfPoints, pt1, pt2 ) ) { points.append( pt1 ); points.append( pt2 ); } delete circle1; delete circle2; return es; } static Acad::ErrorStatus intLine( Custom* custom, const AcDbLine* line, AcDb::Intersect intType, const AcGePlane* projPlane, AcGePoint3dArray& points) { Acad::ErrorStatus es = Acad::eOk; AcGeLineSeg3d lnsg(line->startPoint(), line->endPoint()); es = intLine(custom, lnsg, points); return es; } Acad::ErrorStatus Custom::intersectWith( const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, int /*thisGsMarker*/, int /*otherGsMarker*/) const { assertReadEnabled(); Acad::ErrorStatus es = Acad::eNotImplementedYet; if (ent == NULL) { return Acad::eNullEntityPointer; } if (ent->isKindOf(AcDbLine::desc())) { if ((es = intLine((class Custom *const)this, AcDbLine::cast(ent), intType, NULL, points)) != Acad::eOk) { return es; } } /* else if (ent->isKindOf(AcDbArc::desc())) { if ((es = intArc(this, AcDbArc::cast(ent), intType, NULL, points)) != Acad::eOk) { return es; } } else if (ent->isKindOf(AcDbCircle::desc())) { if ((es = intCircle(this, AcDbCircle::cast(ent), intType, NULL, points)) != Acad::eOk) { return es; } } */ return es; }