walkinside / sdk

Develop powerful desktop and web applications on top of Walkinside 3D engine
4 stars 4 forks source link

CAD/FRT Hierarchy file display and attachment #23

Closed AgLaApps closed 7 years ago

AgLaApps commented 7 years ago

Good morning,

We want to create a plugin to display the files (pdf, png, txt) attached to the CAD or FRT hierarchy of the selected element in the scene. Right now in the plugin we display all the files in a specific folder, so now we want to know the best approach to attach the files to the CAD or FRT and then when a specific element is selected display the files attached to it.

Thanks in advance.

kveretennicov commented 7 years ago

@aglaapps, when you say "we display all the files in a specific folder", you mean that each branch with attached documents has a corresponding folder on disk? How do you find that folder for the branch? By branch name?

AgLaApps commented 7 years ago

Right now we have a folder inside the model folder and we display all the files in that folder and sub-folders.

http://imgur.com/TqgQlPy

The next step we want to do is attach documents to elements of the model and when the element is selected display the related documents, so we want to know the best way and approach, if the best way is to have a folder for each branch with the branch name then we will head towards that. Also we want to know what is the best way to get the information (name, id, etc...) of the selected element.

kveretennicov commented 7 years ago

@aglaapps, one thing you can do is assign a Walkinside attribute to the branch. The value of the attribute will link to the list of documents related to that branch. This can be done in either Viewer SDK or Data SDK:

// Viewer SDK variant

var aglaAppsPrefix = "aglaapps/<something unique>";  // Use something sufficiently unique
                                                     // for the name, so it doesn't conflict with
                                                     // other plug-ins.
var attributeName = aglaAppsPrefix + "/docs-key";
var attributeValue = "..."; // Some unique identifier for the branch;
                            // here I assume that branches do not have names that are unique
                            // or any engineering attribute that is unique, so the identifier will
                            // be generated by you. 

// Create a data entity that will hold document list for the branch.
IVRProject project = ...;
var docsEntityClassName = aglaAppsPrefix + "/branch-docs";
var docsFields = new Dictionary<string, object>
{
    {"docs-key-reference": attributeValue},
    {"doc-1": "doc123.txt"},
    {"doc-2": "images\\image456.png"},
    ... // Any other docs attached to the branch.
};
project.EntityManager.Create(docsEntityClassName, docsFields);

// Link branch to the data entity using custom branch attribute.
IVRBranch branch = ...;
branch.SetValue(attributeName, attributeValue);
// Data SDK variant - basically the same with minor differences

var attributeName = "...";
var attributeValue = "...";

IProject project = ...;
var attributeKey = project.AttributeSources.Walkinside().CreateKey(attributeName);

// Create a data entity that will hold document list for the branch.
var entityClassName = "...";
var docsFields = ...;
project.Entities.Create(entityClassName, docsFields);

// Link branch to the data entity using custom branch attribute.
IBranch branch = ...;
branch.Attributes.Set(attributeKey, attributeValue);

After you have prepared the project in this way, this is how to find back attached documents in the Viewer plug-in:

// Subscribe to selection change notifications.
IVRProject project = ...;
project.BranchManager.SelectionChanged += this.SelectionChanged;

...

private void SelectionChanged(object sender, VRBranchesEventArgs args)
{
    var attributeName = "..."; // The one used above, in project preparation phase.
    var docsEntityClassName = "..."; // The one used above, in project preparation phase.

    // Go over each selected branch.
    foreach (var branch in args.Branches)
    {
        var docsKey = branch.GetValue(attributeName);
        if (docsKey == null)
        {
            continue; // No documents attached to this one.
        }

        // Find back the doc entity linked to the branch.
        var docsEntities = project.EntityManager.GetByAttribute(
            docsEntityClassName, "docs-key-reference", docsKey);

        // Normally you should keep only one doc entity per branch.
        var docs = docsEntities.Single();

        IDictionary<string, object> docsFields = docs.GetAttributes();
        // Your "doc-1", "doc-2", etc. for the branch are now in the docsFields dictionary,
        // they can be retrieved and displayed.
    }
}

The reason why I don't just store the list of documents directly in the branch attribute is that it has a length limit. So attribute value may not be able to fit the entire list of documents.

Let me know if something is not clear or doesn't work in this approach and we'll figure out something else.

kveretennicov commented 7 years ago

Closing for now. Feel free to re-open for further questions.