How to set current UCS

How to set current UCS

Anonymous
Not applicable
2,516 Views
9 Replies
Message 1 of 10

How to set current UCS

Anonymous
Not applicable
Currently, I have 2 UCS ( "world" and "xxx")
I want to set "xxx" as current UCS in my code. after then
use ads_command(RTSTR, _T("_.UCS"), RTSTR, _T("_Move"), RTSTR, _T("\\"), RTNONE)) == RTNORM) to let user select a new point.

But alway create a UCS("unnamed").
0 Likes
2,517 Views
9 Replies
Replies (9)
Message 2 of 10

Anonymous
Not applicable
I don't know if there is any command can set a certain ucs to current.
Or is there any API to do so.
0 Likes
Message 3 of 10

Anonymous
Not applicable
You might try looking up acedSetCurrentUCS in the sdk docs

Daniel
0 Likes
Message 4 of 10

cadMeUp
Collaborator
Collaborator
Here is a little routine you can use that will set the WCS to UCS, allow to pick a new origin, and set the UCS origin to the picked point:

AcGeMatrix3d mat;

// Set to world UCS
mat.setCoordSystem(AcGePoint3d(0,0,0), AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis);
acedSetCurrentUCS(mat);

// Setup the new UCS
AcGePoint3d ucsOrig(5, 10, 12);
AcGeVector3d zAxis(0.3, 1.92, 0.89);
AcGeVector3d xAxis = zAxis.perpVector();
AcGeVector3d yAxis = zAxis.crossProduct(xAxis);
xAxis.normalize();
yAxis.normalize();
zAxis.normalize();
mat.setCoordSystem(ucsOrig, xAxis, yAxis, zAxis);
acedSetCurrentUCS(mat);

// Translate the UCS (world) origin for use in acedGetPoint (optional).
AcGePoint3d transPnt;
acdbWcs2Ucs(asDblArray(ucsOrig), asDblArray(transPnt), false);

AcGePoint3d pnt;
if(acedGetPoint(asDblArray(transPnt), _T("\nPick UCS origin: "), asDblArray(pnt)) != RTNORM)
return;
pnt.transformBy(mat);

// Set the UCS to the point picked.
mat.setCoordSystem(pnt, xAxis, yAxis, zAxis);
acedSetCurrentUCS(mat);
0 Likes
Message 5 of 10

Anonymous
Not applicable
Thanks cadmeup
acedSetCurrentUCS takes the parameter AcGeMatrix3d, which only contain the information of position and axis.

For example, I have two UCS(WORLD, testUCS),
And when I get the the matrix of testUCS and then set it, it will only copy the position and axis information to current UCS. But what I want is set the testUCS to current.


AcDbUCSTable *pUcsTbl;
acdbHostApplicationServices()->workingDatabase()
->getUCSTable(pUcsTbl, AcDb::kForRead);
if (!pUcsTbl->has(_T("testUCS")))
{
pUcsTbl->close();
return false;
}
// get UCS table record
AcDbUCSTableRecord *pUcsTblRcd;
pUcsTbl->getAt(_T("testUCS"), pUcsTblRcd, AcDb::kForRead);

//Get UCS Matrix
AcGeMatrix3d mat;
AcGeVector3d vecXAxis, vecYAxis, vecZAxis;
vecXAxis = pUcsTblRcd->xAxis();
vecYAxis = pUcsTblRcd->yAxis();
vecZAxis = vecXAxis.crossProduct(vecYAxis);
mat.setCoordSystem(pUcsTblRcd->origin(), vecXAxis,
vecYAxis, vecZAxis);
pUcsTblRcd->close();
pUcsTbl->close();
// set UCS_OLP to current UCS
acedSetCurrentUCS(mat);
0 Likes
Message 6 of 10

Anonymous
Not applicable
you can set the current ucs for the active viewport like this

{code}
static void ArxSetUcs_doit(void)
{
Acad::ErrorStatus es = Acad::eOk;
{
AcDbDatabase *pDb =
acdbHostApplicationServices()->workingDatabase();

AcDbUCSTablePointer
pUCSTable(pDb->UCSTableId(), AcDb::kForRead);

if( (es = pUCSTable.openStatus()) != Acad::eOk )
{
acutPrintf(ACRX_T("Fail %s @ Line %d"),
acadErrorStatusText(es), __LINE__);
return;
}

AcDbViewportTablePointer pViewportTable
(pDb->viewportTableId(), AcDb::kForRead);

if((es = pViewportTable.openStatus()) != Acad::eOk)
{
acutPrintf(ACRX_T("Fail %s @ Line %d"),
acadErrorStatusText(es), __LINE__);
return;
}

AcDbObjectId activeViewPortId;

if((es = pViewportTable->getAt
(_T("*Active"),activeViewPortId)) != Acad::eOk)
{
acutPrintf(ACRX_T("Fail %s @ Line %d"),
acadErrorStatusText(es), __LINE__);
return;
}

AcDbViewportTableRecordPointer
pActiveViewportTableRecord
(activeViewPortId, AcDb::kForWrite);

if((es = pActiveViewportTableRecord.openStatus())
!= Acad::eOk)
{
acutPrintf(ACRX_T("Fail %s @ Line %d"),
acadErrorStatusText(es), __LINE__);
return;
}

if( pUCSTable->has(_T("testUCS") ))
{
AcDbObjectId testUCSId;
if( (es = pUCSTable->getAt
(_T("testUCS"),testUCSId) ) != Acad::eOk )
{
acutPrintf(ACRX_T("Fail %s @ Line %d"),
acadErrorStatusText(es), __LINE__);
return;
}

if(!testUCSId.isNull())
{
pActiveViewportTableRecord->setUcs(testUCSId);
}
}
}

if((es = acedVportTableRecords2Vports())
!= Acad::eOk)
{
acutPrintf(ACRX_T("Fail %s @ Line %d"),
acadErrorStatusText(es), __LINE__);
return;
}
}
{code}
0 Likes
Message 7 of 10

cadMeUp
Collaborator
Collaborator
It's kind of confusing with the code you posted, because it looks like it should set the WCS to a UCS (to a current UCS) with the values that are stored within the UCS table record, if they are different from WCS or the current UCS.

When you create a AcDbUCSTableRecord it is initialized like this:
"Initializes the UCS origin to (0,0,0), the UCS X axis to (1,0,0), and the UCS Y axis to (0,1,0) in WCS coordinates."

It is basically set as a world UCS (WCS).

If you don't change any of the values that are stored with this UCS, whenever you open it and try to set it as "current" it will always seem like it doesn't have any effect, unless your current UCS is something other than WCS. You have to open the 'testUCS' for write and call the class methods 'setXAxis', 'setYAxis', and 'setOrigin' (and possibly 'setUcsBaseOrigin'). The next time you open this UCS record it will have values that might be other than WCS values and it will reflect a different coord sys. 'acedSetCurrentUCS' won't change any values that may be stored with the 'testUCS' record.

Also, before you set the record to the UCS table make sure you give it a name using 'AcDbSymbolTableRecord::setName' that is a unique name within the UCS table, or with a name of a record that you want to replace within the table.

Hope it makes sense yelixing! UCS's can get confusing sometimes.
0 Likes
Message 8 of 10

Anonymous
Not applicable
Thanks cadmeup and danielm103

I found a way, ads_command(RTSTR, _T("_.UCS"), RTSTR, _T("NAmed"), RTSTR, _T("Restore"),
RTSTR, _T("testUCS"), RTNONE);
0 Likes
Message 9 of 10

Anonymous
Not applicable
Thanks danielm103, your solution worked, even on the modeless dialog case.

One additional point:

before acedVportTableRecords2Vports(), need close VportTable and its record.
0 Likes
Message 10 of 10

Anonymous
Not applicable
Glad it works for you,
The smart pointers should close those items, I added a extra set of braces for the scope.. I should have made a comment
0 Likes