Community
Navisworks API
Welcome to Autodesk’s Navisworks API Forums. Share your knowledge, ask questions, and explore popular Navisworks API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Navisworks Timeliner API

21 REPLIES 21
Reply
Message 1 of 22
Nchapman1616
4967 Views, 21 Replies

Navisworks Timeliner API

I'm new to the Navisworks API and am trying to export all the timeliner information shown in image attached(timeliner.png)  associated with all objects out to a txt file but can't seem to figure out how to do it.  I've got the Item displayname(Revit name and ID) to export and the higher level Task information but can't seem to get down another level and get the items timeliner info.  I've looked at examples but cant seem to get it work Can someone please help with this.

 

Here is the Item display name code I'm used not sure if this is even the approach to use:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;

namespace BasicPlugIn
{
 [PluginAttribute("BasicPlugIn.ABasicPlugin",

                     "ADSK",

                     ToolTip = "BasicPlugIn.ABasicPlugin tool tip",

                     DisplayName = "Sample Plugin")]

public class ABasicPlugin : AddInPlugin
    {

        public override int Execute(params string[] parameters)
        {
            string myPath = @"C:\Revit Projects\test.txt";

            using (StreamWriter myText = File.CreateText(myPath))

                foreach (ModelItem item in

              Autodesk.Navisworks.Api.Application

              .ActiveDocument.Models.RootItemDescendantsAndSelf)
                {

                    string dname = item.DisplayName;
                    myText.WriteLine(dname);
                }

            return 0;
}
}
}



 

 

Thanks,

Nate

21 REPLIES 21
Message 2 of 22
ngombault
in reply to: Nchapman1616

Hi Nate,

 

What you are looking for is the category.displayname "Timeliner" and all its DataProperty.values

 

For each modelitem you can look into the .PropertyCategories collection find the PropertyCategory with the DisplayName "Timeliner" and read the value of each DataProperty in the .Properties collection.

 

You can also use the functions of .PropertyCategories.FindPropertyByDisplayName, .FindCategoryByName etc. to retrieve specific properties.

 

be aware that the returned value of a DataProperty has an internal Navisworks type DataVariant that you need to convert to string to be able to write it in your text file.

 

 

Also, having written a plugin like that myself (for xml export) I would recommend to loop on the timeliner tasks and get the attached selection of each task, or to loop on a Search with .PruneBelowMatch property set to true. Looping on modelitem like you intend to will export duplicate information for parent nodes and their children when/if a high level node is attached to a task...

 

Good luck

 

 /Edit: The DisplayName is Case sensitive, and in the case of TimeLiner, it is a capital L.

Message 3 of 22
xiaodong_liang
in reply to: ngombault

just a complement on the basis of ngombault's comment, we have a blog on the relevant knowledge:

http://adndevblog.typepad.com/aec/2012/05/navisworks-net-api-properties.html

Message 4 of 22
Nchapman1616
in reply to: ngombault

Thanks for all the helpSmiley Happy   i was able to get the info out but like you said im getting duplicate info. Can you guys explain how to filter like you were talking about PruneBelowMatch and timeliner task.  Basically i want the export to look like this with one item and all info below.

COUNTERTOP-TYPICAL-GENERIC-PLAM [519771]

LcOdpTimeLinerProperty_TasksContainedCountInt32:1
LcOdpTimeLinerProperty_TasksAttachedCountInt32:0
LcOdpTimeLinerProperty_ContainedOverlapBoolean:False
LcOdpTimeLinerProperty_SelectedOverlapBoolean:False
LcOdpTimeLinerProperty_ContainedTask1DisplayString:Cabinet - Upper
LcOdpTimeLinerProperty_ContainedTask_BaseStart1DateTime:2/13/2013 12:00:20 AM
LcOdpTimeLinerProperty_ContainedTask_BaseEnd1DateTime:2/13/2013 10:00:20 AM

Message 5 of 22
ngombault
in reply to: Nchapman1616

when a 3D object is attached to a task, it get both the "Conatined_" & "Attached_" properties in the Property tab, and all its children (recursively) get the "Contained_' properties only.

 

So first thing is to only report the "Contained_" properties.

 

Second you could try to only report top level objects (the one having the "Attached_" properties as well). To do that you can try either using LINK to filter the modelitem from the DescendantAndSelf collection you are already looking at, or use a more "Navisworks-Like" way and try creating a Search that looks for item with the Timeliner Property, and "PruneBelowMatch" which means if an item matches the criteria it doesn't look into its children

 

        Dim S As Search = New Search With {.PruneBelowMatch = True, .Locations = SearchLocations.none}
        S.Selection.SelectAll()
 S.SearchConditions.Add(SearchCondition.HasPropertyByDisplayName("TimeLiner", "WhateverPropertyDisplayName"))

        ActiveDocument.CurrentSelection.CopyFrom(S.FindAll(ActiveDocument, False))

 

the API doc gives good sample for the Search objects...

 

 

Message 6 of 22
Nchapman1616
in reply to: ngombault

Thanks for the Help!Smiley Happy

Message 7 of 22
Nchapman1616
in reply to: ngombault

Sorry i have one more question for you.  How would i go about getting the total duration of the task and when that task starts in the sequence.  I think the path i would take is now that i know what task the item is associated with i can look that task up and pull the information.  If this is the right way how would i go about it.  Here is my current code

 

 

using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
using Autodesk.Navisworks.Api.Timeliner;

namespace BasicPlugIn
{
    [PluginAttribute("BasicPlugIn.ABasicPlugin",

                        "ADSK",

                        ToolTip = "BasicPlugIn.ABasicPlugin tool tip",

                        DisplayName = "Sample Plugin")]

    public class ABasicPlugin : AddInPlugin
    {
        public override int Execute(params string[] parameters)
       {
         Search s = new Search();
                        s.Locations = SearchLocations.None;
                        s.PruneBelowMatch = true;
                        s.Selection.SelectAll();
                        s.SearchConditions.Add(SearchCondition.HasPropertyByDisplayName("TimeLiner","Tasks Attached to"));
                        ModelItemCollection collection = s.FindAll(Autodesk.Navisworks.Api.Application.ActiveDocument, false);
    
            string myPath = @"C:\Revit Projects\test.txt";
            using (StreamWriter myText = File.CreateText(myPath))

            foreach (ModelItem item in collection)
            {
                myText.WriteLine(item.DisplayName.ToString());
                PropertyCategory oPc = item.PropertyCategories.FindCategoryByDisplayName("TimeLiner");
                {
                    foreach (DataProperty oDp in oPc.Properties)
                    {
     
                                myText.WriteLine(oDp.Name + oDp.Value.ToString());
                            }    
                
                    }

            }
               return 0;  
            }

        }
    
    }

Message 8 of 22
ngombault
in reply to: Nchapman1616

This is why I previously suggested to loop on the Timeliner task rather than on the model item, from the timeliner task you can get the start, end, duration, and some custom field from the datasource, much more than what the Property panel currently offers. you will still be able to get all the item attached to the task, by getting its ".Selection" property and all its content.

 

If you keep on with your current approach though, you gonna have to loop through the timeliner task anyway, and for each item, look for a task with the same name as the "Attached to" Property. Be carefull task nae is not required to be unique, thus I recommend checking some of the task attributes as well (task.displayname = "Attached to", task.start = "Attached to Planned Start"...).

Besides, doing this, will eventually force you to look multiple times for the same task (if you have several item attached to that task).

Message 9 of 22
Nchapman1616
in reply to: ngombault

Thanks so much for the help.Smiley Happy I will see what i can do with this new approach.

 

thanks,

Nate

Message 10 of 22
Nchapman1616
in reply to: ngombault

I thought i was on the right track but apparently im not.  why doesnt this code work?

 

            Nw.Document doc = Nw.Application.ActiveDocument;

            Nw.DocumentParts.IDocumentTimeliner tl = doc.Timeliner;

            Tl.DocumentTimeliner tl_doc = (Tl.DocumentTimeliner)tl;

            foreach (Tl.TimelinerTask oTask in tl_doc.Tasks)
            {
             

                foreach (Tl.TimelinerTask childtask in oTask.Children)
                {

                    Tl.TimelinerSelection timeLinerSelection = childtask.Selection;
                   
                    if (timeLinerSelection != null)
                    {
                        
                        if (timeLinerSelection.HasExplicitSelection)
                        {
                         
                            Nw.ModelItemCollection oExplicitSel = timeLinerSelection.ExplicitSelection;
                            foreach (Nw.ModelItem moDel in oExplicitSel)
                            {
                                
                                Nw.ModelItem modelParent = moDel.Parent;
                                Nw.PropertyCategoryCollection propCatCollection = modelParent.PropertyCategories;
                                foreach (Nw.PropertyCategory propCat in propCatCollection)
                                {
                                   
                                    if (propCat.DisplayName.ToString() == "Element ID")
                                    {
                                        string eleID = propCat.Properties.FindPropertyByDisplayName("Value").Value.ToString();

                                        MessageBox.Show(eleID);

 

Thanks Again,

Nate

Message 11 of 22
ngombault
in reply to: Nchapman1616

ExplicitSelection is just one of the many Selection types a task can have, like SelectionSet, SearchSet and combination of these.

 

What you are looking for is the .GetSelectedItem function of the Selection Object, that will give you a generic ModelItemCollection that you can loop on.

 

Try using the ObjectBrowser of Visual Studio, or the Autodesk plugin Appinfo (see Example.sln file that comes with the installation of Navisworks), it gives you valuable information on what you cacn do with each object.

Message 12 of 22
Nchapman1616
in reply to: ngombault

Got it to work.  Thanks so much for your help without it i dont know what i would have done.

 

Thanks,

Nate

Message 13 of 22
m.ridi220
in reply to: xiaodong_liang

@xiaodong_liang @ngombault is there  a way to export instead in *.csv format of *.txt format? Could you suggest to me what part of code I have to change please?

Message 14 of 22
ngombault
in reply to: m.ridi220

The code above already writes to a text file, refer to line:

 

string myPath = @"C:\Revit Projects\test.txt";
            using (StreamWriter myText = File.CreateText(myPath))

 If it doesn't make sense to you, then you have a few more things to learn than Navisworks API 🙂

Message 15 of 22
m.ridi220
in reply to: ngombault

@ngombault if I want to get the duration of each tasks in the timeliner is:

foreach (PropertyCategory propCat in propCatCollection)
 {
  if (propCat.DisplayName.ToString() == "Element ID")
   {
     string eleID = propCat.Properties.FindPropertyByDisplayName("Value").Value.ToString();
     MessageBox.Show(eleID);
     myText.WriteLine(oTask.DisplayName.ToString());
     PropertyCategory opc = oTask.ActualDuration("TimeLiner");

But there is an error in the last row, how I should fix it?

Thanks!

 

Message 16 of 22
ngombault
in reply to: m.ridi220

Since you didn't provide much context, assuming:

1. oTask is the TimelinerTask in a foreach loop on timeliner tasks

2. and propCatCollection is the collection of propertycategories on one ModelItem in a foreach loop on the selected items of that oTask

 

Then I suggest:

a. That you use FindPropertyByDisplayName("Element ID","Value") directly on the propCatCollection rather than iterating the way you do

b. That you extract the actual duration in the timerliner task loop, not in the modelitem secondary loop

c. That you use oTask.ActualDuration() which is a nullable Timespan, not sure what you are trying to do with ActualDuration("Timeliner"), it appears you have mixed up PropertyCategories and Timerliner Tasks Properties.

Message 17 of 22
minh.hn
in reply to: m.ridi220

Hi m.ridi220,

 

Please try the following method to get ActualDuration:

//...
//PropertyCategory opc = oTask.ActualDuration("TimeLiner");
TimeSpan time = (TimeSpan)oTask.ActualDuration;
int days = (time.Days == 0) ? 1 : (time.Days + 1);

days is what you are looking for ?

 

Regards,

MinhHN

 

 

 

 

Tags (1)
Message 18 of 22
m.ridi220
in reply to: ngombault

Thanks @ngombault for your suggestion. I'm trying to edit the last code of Nchapman in order to export the actual duration of each task in a txt file.

using System;
using System.Data;
using System.Text;
using System.IO;
using Autodesk.Navisworks.Api.Plugins;
using Nw = Autodesk.Navisworks.Api;
using Ns = Autodesk.Navisworks.Api.Takeoff;
using Tl = Autodesk.Navisworks.Api.Timeliner;

namespace BasicPlugIn
{
    [PluginAttribute("BasicPlugIn.ABasicPlugin",

                        "ADSK",

                        ToolTip = "BasicPlugIn.ABasicPlugin tool tip",

                        DisplayName = "Sample Plugin")]

    public class ABasicPlugin : AddInPlugin
    {
        public override int Execute(params string[] parameters)
        {
            Nw.Search s = new Nw.Search();
            s.Locations = Nw.SearchLocations.None;
            s.PruneBelowMatch = true;
            s.Selection.SelectAll();
            //s.SearchConditions.Add(Nw.SearchCondition.HasPropertyByDisplayName("TimeLiner", "Tasks Attached to"));
            Nw.ModelItemCollection collection = s.FindAll(Autodesk.Navisworks.Api.Application.ActiveDocument, false);

            Nw.Document doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            Nw.DocumentParts.IDocumentTimeliner tl = doc.Timeliner;
            Tl.DocumentTimeliner tl_doc = (Tl.DocumentTimeliner)tl;
            string myPath = @"C:\test.txt";
            using (StreamWriter myText = File.CreateText(myPath))
                foreach (Tl.TimelinerTask oTask in tl_doc.Tasks)
            {
                foreach (Tl.TimelinerTask childtask in oTask.Children)
                {
                    Tl.TimelinerSelection timeLinerSelection = childtask.Selection;

                    if (timeLinerSelection != null)
                    {

                        if (timeLinerSelection.HasExplicitSelection)
                        {

                            Nw.ModelItemCollection oExplicitSel = timeLinerSelection.ExplicitSelection;
                            foreach (Nw.ModelItem moDel in oExplicitSel)
                            {
                                Nw.ModelItem modelParent = moDel.Parent;
                                Nw.PropertyCategoryCollection propCatCollection = modelParent.PropertyCategories;
                                    myText.WriteLine(moDel.DisplayName.ToString());
                                    PropertyCollection pCol = moDel.PropertyCategories.FindPropertyByDisplayName("Element ID", "Value");
                                    {
                                        foreach (Nw.PropertyCategory propCat in propCatCollection)
                                            myText.WriteLine(propCat.Name + propCat.ToString());
                                    }

                                    return 0;

                                }

But in 

PropertyCollection pCol = moDel.PropertyCategories.FindPropertyByDisplayName("Element ID", "Value");

I get the following error: "Cannot Implicity convert type "Autodesl.Navisworks.Api.DataProperty" to "System.Data.PropertyCollection"

Could you help me please?

Message 19 of 22
m.ridi220
in reply to: minh.hn

Thanks @minh.hn for your answer. Could you explain more in detail where I have to insert "TimeSpan" in my code please?

Message 20 of 22
minh.hn
in reply to: m.ridi220

Hi m.ridi220,

 

Sorry, I did not explain in detail.

Based on the TimelineTask document, to get the ActualDuration, use as follows:

 

public TimeSpan? ActualDuration { get; }

 

So, I have to insert "TimeSpan" in my code.

 

Regards,
MinhHN.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


Autodesk Design & Make Report