Quantcast
Channel: MicroStation Programming Forum - Recent Threads
Viewing all 7260 articles
Browse latest View live

RE: [DGN platform] How to update reference location via API

$
0
0

I'm pleased to read that you solved your problem.

However, the best way by far to attach reference files is using a MicroStation configuration variable.  MicroStation configuration variable MS_RFDIR is such a multi-path variable.  You can define one or more paths in MS_RFDIR that MicroStation will search for reference attachments.

If subsequently you change the location of some reference files, it's necessary only to modify the definition of MS_RFDIR to enable MicroStation to find the files in their new location.  For example...

Original reference file location:

c:/refs/

New reference file location:

c:/notRefs/

[DGN platform] How to update reference location via API

$
0
0

Hello everyone,

I'm trying to parse dgn file and update location of it's reference file.

Say I have c:\Main.dgn which has reference c:\refs\Ref1.dgn

And I want it to be moved Ref1.dgn to another location(and maybe name), say c:\notRefs\Ref2.dgn

DGN platform is used for these, not Microstation API, because I don't want Microstation to be launched for this tiny task.

The problem here that I can't update reference location.

File Modified time was changed but reference location remains the same.

Maybe I missed something vital, but I can't get it from the document, nothing there was found.

Thanks,

Artem

So I have the following code (simplified version, removed dozens of checks that pointer is not null and operation returned 0 and so on):

// open & load parent file
auto document = DgnDocument::CreateFromFileName(status, path.c_str(), nullptr, DEFDGNFILE_ID, DgnDocument::FETCH_Write, DgnDocument::FETCH_OPTION_WithSet);

RefCountedPtr<DgnFile> file = DgnFile::Create(*document, DGNFILE_OPENMODE_READWRITE, *DgnRefUpdater::Utils::StaticHostHelper::host);
file->LoadDgnFile(&res);

// Load references from the root model
auto models = file->GetModelIndexCollection();
for (auto it = models.begin(); it != models.end(); ++it)
{
Bentley::StatusInt status_load = 0;
DgnModelP model = file->LoadRootModelById(&status_load, (*it).GetModelId(), true, true, true);

if (status_load == 0)
{

	auto currentAttach = model->FindDgnAttachmentByElementId(elementId);
	if (currentAttach)
	{
		// check it's current path
		auto saved = currentAttach->GetAttachMoniker()->GetSavedFileName();

                // create new moniker
		auto mon = Bentley::DgnPlatform::DgnDocumentMoniker::CreateFromFileName(L"C:\\Users\\Artem\\Documents\\Vault\\ABursuk\\Ref1.dgn");
		DgnDocumentMonikerR newMon = *mon;

                // set new moniker to the reference
		currentAttach->SetAttachMoniker(newMon);

                // save changes
		auto sts = file->ProcessChanges(Bentley::DgnPlatform::DGNSAVE_APPL_INITIATED);

                break;
	}
}

RE: [CONNECT] Delivering an Application

$
0
0

Hi Jon,

I am not sure I can be a lot of help in this area, but which installer software or toolkit are you using?  I have some lite-weight use of Microsoft Visual Studio installer projects back in 2010; which appears to be a separate download in 2015 (Microsoft Visual Studio 2015 Installer Projects).  A number of our product installers we use are built off a framework over WixToolset (some Visual Studio integration information here: Working in Visual Studio (2015)).

I would think the installer APIs would provide either a Product or Registry search capability either directly or under a utility class (possibly requiring additional elevation), but my hands-on knowledge here is quite limited.

Bob

RE: [CONNECT] Delivering an Application

$
0
0

[quote user="Robert Hook"]I would think the installer APIs would provide either a Product or Registry search capability[/quote]

Yes, they do.

[quote user="Robert Hook"]I am not sure I can be a lot of help in this area[/quote]

On the contrary: you and Yongan have both provided valuable information and insight.  I have, in the past, taken a guess at installation locations and Registry details but found my guess inaccurate.

[quote user="Robert Hook"]Which installer software or toolkit are you using?[/quote]

I like Lindersoft's SetupBuilder.  It's straightforward to use, and has fantastic support.  I stopped using InstallShield after it arbitrarily decided my license was invalid and the company proved to be incapable of investigating, let alone solving, my problem.

RE: [CONNECT C++] mdlLevelIterator_setIterateType()

$
0
0

Attempting to use the LevelCache to remove unused levels, but the sample "To remove a level while iterating" in the help file isn't quite right. The compiler is choking on levelCache.RemoveLevel(). That function only seems to exist for FileLevelCache elements, not EditLevelHandle.

RE: [CONNECT C++] mdlLevelIterator_setIterateType()

$
0
0
yep, mdlLevelIterator_setIterateType() does the exact same thing whether you pass LEVEL_ITERATE_TYPE_UNUSED_LEVELS or LEVEL_ITERATE_TYPE_USED_LEVELS.
At present I don't see a good workaround.
A bad workaround is to iterate used levels and all levels and take the difference to get unused levels.

RE: [CONNECT C++] mdlLevelIterator_setIterateType()

$
0
0
DgnFile::GetLevelCacheR() returns a FileLevelCacheR. Just declare your variable of that type instead of the LevelCacheR type used in the sample.

RE: [CONNECT C++] mdlLevelIterator_setIterateType()

$
0
0

I think one or two of the MDL functions have developed faults as their functionality has been refactored into classes.

In your case, the FileLevelCache or LevelCache class may provide a solution.  Look in MicroStationAPI help for topic Iterate levels in a level cache.

For example...

DgnModelP pActiveModel = ISessionMgr::GetActiveDgnModelP();
LevelCacheCR lvlCache = pActiveModel->GetLevelCache();
for (LevelHandle lvlHandle : lvlCache)
{
  WCharCP pLvlName = lvlHandle.GetName();
}

Methods such as IsLevelUsedInModel() and IsLevelUsedInFile() help you filter while enumerating.


[CONNECT C++] mdlLevelIterator_setIterateType()

$
0
0

While writing a function to delete unused levels in a model, I called mdlLevelIterator_setIterateType(), passing LEVEL_ITERATE_TYPE_UNUSED_LEVELS, and the resulting iterator only contained USED levels. I changed the type to LEVEL_ITERATE_TYPE_ALL_LEVELS and got, as expected, all levels. Finally, I changed it to LEVEL_ITERATE_TYPE_USED_LEVELS and got the same as the first try - all used levels. I checked the enum values, and LEVEL_ITERATE_TYPE_UNUSED_LEVELS and LEVEL_ITERATE_TYPE_USED_LEVELS have different values, but they both returned the same results...

RE: [CONNECT] Delivering an Application

RE: [CONNECT] Delivering an Application

$
0
0

[quote user="Robert Hook"]this FAQ may be of some help[/quote]

There are similar questions on SetupBuilder's user Forums.  In response to some of my questions, Lindersoft added functionality to SetupBuilder to help install a DLL app. to a MicroStation installation  8-)

RE: [CONNECT C++] mdlLevelIterator_setIterateType()

$
0
0

Just in case anyone else is removing unused levels, this is what is working for me:

FileLevelCache& fileLevelCache = mdlModelRef_getActive()->GetDgnFileP()->GetLevelCacheR();
for (EditLevelHandle level (fileLevelCache.begin()); level != fileLevelCache.end(); )
{
	if ( !fileLevelCache.IsLevelUsedInModel(mdlModelRef_getActive(),level.GetLevelId()) )
	{
		if ( fileLevelCache.RemoveLevel (&level, level) == LevelCacheErrorCode::None ) // modifies level to point to the next level in the cache
		{
			fileLevelCache.Write();
		}
	}
	else
	{
		++level;
}

 

 

Bruce

RE: [CONNECT C++] Placing Cells - An Implementation Question

$
0
0

[quote user="Bruce Reeves SRNS"]My thought is that the constant "read" of the cell from the library on the server would be a big performance "hit"[/quote]

Maybe it is, and maybe it isn't.  You don't know until you measure it.  Beware of unnecessary premature optimisation.

Your idiom of reading the cell when the tool starts reduces any potential library read problem.  Use EditElementHandles  instead of element descriptors: they provide useful traits for managing the internal descriptor when copying a handle.  Use DgnElementSetTool as your tool's base class.

RE: [CONNECT C++] Placing Cells - An Implementation Question

$
0
0

For obtaining cells from a network storage location (LAN/WAN) there will always be some file access latency issues. However as you state (1) elmdscr (now in memory) read from the library (over network), and transform (in memory) elmdscr for placement should be near optimal.

HTH,
Bob

[CONNECT C++] Placing Cells - An Implementation Question

$
0
0

I've got numerous "tools" that essentially place a cell. In thinking about upgrading these tools to CONNECT, I'm wondering if my method could be improved. The cell libraries reside on a server. In V8i, my typical approach is to read the cell into a MSElementDescr, with a scale of 1.0, rotation of 0.0, and an origin of 0,0,0. In the tool's dynamics functions, I duplicate the ElementDescr, transform it with TransformInfo, display it, then release it.

I'm wondering if I update my code to where the cell is initially read with my desired scale, rotation, and origin, then just displayed in the dynamics function, if that's any "better" (no duplication of ElementDescr). My thought is that the constant "read" of the cell from the library on the server would be a big performance "hit", or maybe CONNECT, when started, caches the cell library locally in memory such that there may be no real "penalty" for always "reading" the cell.

 

Bruce

 


RE: ModelReference & Attachment base class for polymorphism

$
0
0
using Bentley.Interop.MicroStationDGN;
using Bentley.MicroStation.InteropServices;
using BNS = Bentley.Interop.MicroStationDGN;

namespace Scanners
{
    public class Scannable : IScanMe
    {
        protected ModelReference ModelReference;
        protected Attachment Attachment;
        public Scannable(ModelReference scannableObject)
        {
            this.ModelReference = scannableObject;
        }
        public Scannable(Attachment scannableObject)
        {
            this.Attachment = scannableObject;
        }

        public ElementEnumerator Scan()
        {
            ElementEnumerator eE = null;
            if (this.ModelReference != null)
            {
                eE = this.ModelReference.Scan();
            }
            if (this.Attachment != null)
            {
                eE = this.Attachment.Scan();
            }
            return eE;
        }
    }
}


namespace Scanners
{
    public interface IScanMe
    {
        ElementEnumerator Scan();
    }
}

This works, but it is exactly what I'm trying to avoid.  If anyone has a better solution, I would appreciate it.  I tried to get reflection/dynamic working to no avail.  I think reflection requires loading in the assemblies, which is undesirable.

RE: ModelReference & Attachment base class for polymorphism

$
0
0

Unfortunately I do not see an Interface available similar to what you describe. Since an attachment is a specialized case of model reference the only way to treat both types in a similar sense via the COM object model would be to detect the model reference type as being an attachment; then use Attachment.MdlModelRefP passing the model reference to code that performs necessary operations in a similar manner.

HTH,
Bob

RE: ModelReference & Attachment base class for polymorphism

$
0
0
That should work. I'll just have to write this portion in C++/CLI and call into native code. Thanks!

ModelReference & Attachment base class for polymorphism

$
0
0

I am wanting to use polymorphism to Scan() with ModelReference & Attachment instances.  

Do these classes implement a similar interface?  

Something like IScannable?

I see that Attachment inherits from Element, but not so with ModelReference.  I was not seeing an abstract base class/interface for the shared methods.

Thanks!

I am writing in C#/C++/CLI on V8i.

RE: How to disable or enable the Menuitem or Toolitem of microstation using c#?

$
0
0

[quote user="Sudhakar Arimanda"]I am developing an addin for MicroStation ...[/quote]

Please follow the MicroStation Programming forum best practices.

Identify Your Platform

Please identify the version of MicroStation, or other product such as PowerDraft, that you are using: MicroStation CONNECT or MicroStation V8i. What is the 8-digit version number (e.g. 10.xx.yy.zz) of MicroStation?

If you're using MicroStation in a ProjectWise (PW) managed environment, let us know that too.

The APIs supplied with MicroStation CONNECT are different to those supplied with MicroStation V8i. Consequently, our answers are likely to be different.

Build Tools

Are you using Visual Studio or Bentley Make (bmake) to build your project? What version of Visual Studio are you using?

Code Syntax Highlighting

When you post code, use the Forum advanced editor's syntax highlighting tool. That's the icon that resembles a pencil:  Syntax Highlighter

Viewing all 7260 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>