Hello,
In the SDK is the example "ViewInfoExample". I build it, but it's not working correctly.
If I change the Origin of the ACS in any View, the "View Info Description" doesn't show this change. Closing and reopening these windows doesn't help. "ACS origin:" is allways listed as "(0,0,0)".
/resized-image/__size/320x240/__key/communityserver-discussions-components-files/343173/ACSorigin_2D00_bug.jpg
I added in my own mdl-app a new line with the acs Name and I got the correct output for each view. But I'm not able to define new ACS's with my app.
How am I able to set a new ACS with my own Parameters and get the exsisting ACS-Information?
I saw the "mdlACS_"-Functions, but they are not well documented and without a example I'm lost at the moment.
Im running Windows 10, 64 Bit, VS Community 2017, Net Framework 4.6.2, MicorStation Connect Edition V.10.15.00.74 (German)
Best regards Ole Gottwald
Because the example of "ViewInfoExample" is not working correctly and I wasn't able to find examples in this forum, I'll share my code here
A function to create a new ACS and set it as activ acs of a specific view (C++):
static void setAcs() { DgnModelRefP modelRef = mdlModelRef_getActive(); // get Active Model if (NULL == modelRef) return; const double uor = mdlModelRef_getUorPerMaster(modelRef); // get Units of Resolution RotMatrix acsRot; acsRot.InitIdentity() // define a Rotation Matrix DPoint3d acsOrigin = DPoint3d::From(99.0 * uor, 20.0 * uor, 30.0 * uor); // define a Origin in Master Units IAuxCoordSysPtr acs = IACSManager::GetManager().CreateACS(); // Create a ACS-Pointer if (acs.IsValid()) { acs->SetOrigin(acsOrigin); acs->SetName(L"Acs Name"); acs->SetRotation(acsRot); acs->SetType(ACSType::Rectangular); acs->SetFlags(ACSFlags::Default); acs->SetDescription(L"Acs Description"); acs->SetScale(1.0); acs->SaveToFile(modelRef, ACSSaveOptions::AllowNew); } // Add Information to the ACS-Pointer ViewportR vp = * IViewManager::GetManager().GetActiveViewSet().GetViewport(viewInfoTestData.viewNo); // Get ViewportReference : viewInfoTestData.viewNo is a int IACSManager::GetManager().SetActive(acs.get(), vp ); // sets the created ACS as Active in the View-Number }
In the documentation of the function IViewManager::GetViewport(int viewNum) the datatype is IndexedViewportP (IViewManager). But u can use the datatype Viewport instead.
You need a variable vp with datatype ViewportR for the function IACSManager::SetActive(IAuxCoordSysP auxCoordSys, ViewportR vp).
And I show, how I get some information from the activ acs:
static void viewinfo_showViewInfo(MSDialog *dbP) { dbP = mdlDialog_findByTypeAndId(RTYPE_DialogBox, DIALOGID_ViewInfo, NULL); DgnModelRefP model = mdlModelRef_getActive(); if (NULL == model) return; DgnFileP file = mdlModelRef_getDgnFile(model); if (NULL == file) return; ViewGroupCollectionCP vgc = &file->GetViewGroups(); ViewGroupP activeViewGroup = vgc->GetActiveP(); if (NULL == activeViewGroup) return; ViewInfoCR viewInfo = activeViewGroup->GetViewInfoR(viewInfoTestData.viewNo); WString sTemp, sInfo; sTemp = viewinfo_getStandardViewInfo(viewInfo); sInfo += sTemp; WChar pLabel[MAX_UNIT_LABEL_LENGTH]; const double uor = mdlModelRef_getUorPerMaster(model); mdlModelRef_getMasterUnitLabel(model, pLabel); sTemp.Sprintf(L"Auflösung (uor): %f per Abstand %s \n", uor, pLabel); sInfo += sTemp; IAuxCoordSysP acs = viewInfo.GetAuxCoordinateSystem(); sTemp.Sprintf(L"\nACS name: %s\n", acs->GetName()); sInfo += sTemp; bool isReadOnly = acs->GetIsReadOnly(); sTemp.Sprintf(L"ACS IsReadOnly: "); if (isReadOnly) { sTemp += L"Yes\n"; } else { sTemp += L"No\n"; } sInfo += sTemp; sTemp.Sprintf(L"ACS description: %s\n", acs->GetDescription()); sInfo += sTemp; sTemp.Sprintf(L"ACS typeName: %s\n", acs->GetTypeName()); sInfo += sTemp; DPoint3d acsOrigin; acs->GetOrigin(acsOrigin); sTemp.Sprintf(L"ACS origin: (%f, %f, %f) \n", acsOrigin.x / uor, acsOrigin.y / uor, acsOrigin.z / uor); sInfo += sTemp; RotMatrix acsRot; acs->GetRotation(acsRot); sTemp.Sprintf(L"ACS rotation (maxAbs): %f \n", acsRot.MaxAbs()); sInfo += sTemp; sTemp.Sprintf(L"ACS scale: %f \n", acs->GetScale()); sInfo += sTemp; sTemp.Sprintf(L"\nClose and reopen the \"ACS\" window, if changes were made!"); sInfo += sTemp; dbP->ItemSetValueByTypeAndId(RTYPE_MultilineText, MLTEXTID_ViewInfoDescription, sInfo.c_str()); }
If there are errors or enhancements, a reply would be nice. Have a nice Day.
Thanks Jon Summers!
Answer Verified By: Ole Gottwald
Ole Gottwald said:If there are errorsRotMatrix acsRot; ... acs->SetRotation(acsRot);
RotMatrix acsRot; ... acs->SetRotation(acsRot);
An uninitialised rotation matrix is good for nothing. Prefer this...
RotMatrix acsRot; acsRot.InitIdentity(); ... acs->SetRotation(acsRot);
Regards, Jon Summers LA Solutions
Is edited!
Without the function InitIdentity(), I'm not able to rotate view for example?
Ole Gottwald said:Without the function InitIdentity(), I'm not able to rotate view for example?
By default, C++ does not initialise a variable. When you write RotMatrix acsRot; the data members of the struct are random.
RotMatrix acsRot;
The identity matrix has zero rotation or scaling. When you write acsRot.InitIdentity(), the data members of the struct are set to meaningful values.
acsRot.InitIdentity()