Get and Set ACS

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

Parents
  • 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 

  • If there are errors
    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?

  • 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.

    The identity matrix has zero rotation or scaling.  When you write acsRot.InitIdentity(), the data members of the struct are set to meaningful values.

     
    Regards, Jon Summers
    LA Solutions

Reply Children
No Data