How to get the file location of a PointCloud file

How to get the file location of a PointCloud file

btmsoftware
Advocate Advocate
3,582 Views
20 Replies
Message 1 of 21

How to get the file location of a PointCloud file

btmsoftware
Advocate
Advocate

In a revit drawing, I need to be able to find the full path of the point cloud files (all of them, rcp AND rcs

 

The following bit of code (VB.NET) allows me to get the cloud instances and the file names but NOt the file path:

 

 Public Function Execute(
      ByVal commandData As ExternalCommandData,
      ByRef message As String,
      ByVal elements As ElementSet) _
    As Result Implements IExternalCommand.Execute

        Dim uiapp As UIApplication = commandData.Application
        Dim uidoc As UIDocument = uiapp.ActiveUIDocument
        Dim doc As Document = uidoc.Document


        Using file As New StreamWriter("c:\temp\result.txt", False)
            Dim clouds As FilteredElementCollector = New FilteredElementCollector(doc).OfClass(GetType(PointCloudInstance))

            For Each cloud As PointCloudInstance In clouds
                file.WriteLine("Found instance: " & cloud.Id.IntegerValue)
                file.WriteLine(vbTab & "Name= " & cloud.Name) ' Seems to contain the filename of the rcp/rcs attached

                Dim files As IList(Of String) = cloud.GetScans()  ' if the point cloud is a rcp, then it contains the list of rcs, otherwise, it contains the rcs
                file.WriteLine(vbTab & "Files:")
                For Each filename As String In files
                    file.WriteLine(vbTab & vbTab & filename)
                Next

                file.WriteLine(vbCrLf & vbCrLf)
            Next

        End Using
        Process.Start("c:\temp\result.txt")
        Return Result.Succeeded

    End Function

 

The result is:

 

Found instance: 2304
	Name= pumpNoInvalidPoints.rcp
	Files:
		pumpNoInvalidPoints_1
		pumpNoInvalidPoints_2
		pumpNoInvalidPoints_3
		pumpNoInvalidPoints_4
		pumpNoInvalidPoints_5

Found instance: 2312
	Name= tester.rcs
	Files:
		tester
		

 

 

Any idea ?

0 Likes
Accepted solutions (3)
3,583 Views
20 Replies
Replies (20)
Message 2 of 21

Anonymous
Not applicable
I don't know which revit version you are working with but I think you are on the wrong track.

You have to make a FilteredElementCollector of RevitLinkInstance . And a RevitLinkInstance does return the path.

0 Likes
Message 3 of 21

btmsoftware
Advocate
Advocate

Remy,

 

I'm testing with Structure 2015

 

It doesn't work. The collection is empty.

 

That makes sense, Point Clouds are not Revit  links, they don't even show up in the Revit Links of the Project browser as shown below

 

Capture.JPG

0 Likes
Message 4 of 21

jeremytammik
Autodesk
Autodesk

Can you find them anywhere in RevitLookup?

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 5 of 21

btmsoftware
Advocate
Advocate

I didn't know about the RevitLookup tables (I'm a newbie with Revit).

 

I'll look into it and will let you know

 

PS: If you have some examples about using those tables, feel free to share Smiley Wink

0 Likes
Message 6 of 21

btmsoftware
Advocate
Advocate

forget my last comment, I'm browsing your blog as we speak, whihc, by the way is an excellent source of information I recommend to everybody as bad as meSmiley Happy

0 Likes
Message 7 of 21

btmsoftware
Advocate
Advocate

Looked into your RevitLookup App from your blog and it doesn;t give the point cloud file path anywere.

 

I guess it has to be stored somewhere since Revit itself can find it but I woudln;t know where to look. Any iother idea ?

0 Likes
Message 8 of 21

jeremytammik
Autodesk
Autodesk

Dear Btmsoftware,

 

Do you see the information you are after in the Revit > Insert > Manage Links dialogue?

 

Please submit a minimal sample RVT file containing a single really small point cloud link that I can open hassle-free and take a look at.

 

Thank you!

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 9 of 21

btmsoftware
Advocate
Advocate

Yes, it gives the relative path to the rcp file, which would be kind of enough for me (then again, I'd prefer the absolute path but I'll take whatever I can get...)

 

Well, I tested by creating a brand new project file in Revit and insterting (after indexing) the poibnt cloud example file I found at http://www.bimblog.ca/2012/01/point-cloud-feature-extraction.html

 

Not sure if I'm allowed to distribute the point cloud file but since it available o nthe web to the public, you can get it. It's quite small and when indexing, there's only 1 rcs file, on top of the rcp file of course, but if we ca nget the rcs full path for 1, we'll be able to get it for multiple....

0 Likes
Message 10 of 21

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Btmsoftware,

 

OK, we are now in business.

 

I grabbed the Zion and Irving samples from the page you mention:

 

http://www.bimblog.ca/2012/01/point-cloud-feature-extraction.html

 

Then I had to figure out how to insert them.

 

I was forced to read the help onUsing Point Cloud Files in a Project:

 

http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-B89AD692-C705-458F-A638-EE7DD83D694C

 

I then needed to find out how to actually Insert a Point Cloud File:

 

http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-B89AD692-C705-458F-A638-EE7DD83D694C

 

I was especially challenged by the two-step process of first converting from a raw format to an indexed RCP version and using the same command a second time to finally insert that.

 

Once I had that, I used the element lister to determine what Revit database elements are generated by inserting a point cloud into the BIM:

 

http://thebuildingcoder.typepad.com/blog/2014/09/debugging-and-maintaining-the-image-relationship.ht...

 

Here are the steps I took and the results obtained in this case:

 

Run the external command Revit > Add-ins > RvtSamples > ADN Abc > 2-1 List all elements.

 

Rename the resulting file:

 

C:\tmp>ren RevitElements.txt RevitElementsBeforePointCloud.txt

 

Insert the point cloud RCP using Revit > Insert > Point Cloud.

 

Run the external command Revit > Add-ins > RvtSamples > ADN Abc > 2-1 List all elements.

 

Rename the resulting file:

 

C:\tmp>ren RevitElements.txt RevitElementsAfterPointCloud.txt

 

Compare the differences to determine the newly added elements:

 

C:\tmp>diff RevitElementsBeforePointCloud.txt RevitElementsAfterPointCloud.txt
3312a3313,3316
> Id=322639; Class=PointCloudType; Category=Point Clouds; Name=zion.rcp;
> Id=322640; Class=Element; Category=?; Name=zion.rcp;
> Id=322641; Class=GraphicsStyle; Category=?; Name=zion.rcp;
> Id=322642; Class=PointCloudInstance; Category=Point Clouds; Name=zion.rcp;

 

As you can see, the process generated a point cloud type and instance, a graphics style, and another element.

 

These four elements can now all be examined using RevitLookup to determine their properties and parameter values.

 

In the past, the file name used for the Revit Element.Name property was the only hint you would get, so you would have to take that a search through your file system using operating system directory traversal functionality to determine the full path.

 

In this case, in addition to that, I would also check what the IsExternalFileReference and GetExternalFileReference methods report.

 

RevitLookup will probably not evaluate them for you. One option you have is to use something more flexible for interactive command line exploration, like the Python or Ruby shells:

 

http://thebuildingcoder.typepad.com/blog/2013/11/intimate-revit-database-exploration-with-the-python...

 

Alternatively, you can implement a macro ar add-in that explicitly calls these methods and reports the result.

 

I decided to take a closer look at the PointCloudType with the element id 322639 in RevitLookup, so I used Revit > Manage > Inquiry > Select by ID > 322639 and then Revit > Add-ins > Revit±Lookup > Snoop Current Selection...

 

No path indeed.

 

Next, I installed the Revit Python shell from

 

https://code.google.com/p/revitpythonshell

 

http://sustain.arch.ethz.ch/DPV/Setup_RevitPythonShell_2015.exe

 

Unfortunately, none of the four elements will admit to being an external file reference:

 

IronPython 2.7.4 (2.7.0.40) on .NET 4.0.30319.18444 (64-bit)
Type "help", "copyright", "credits" or "license" for more information.
>>> doc
<Autodesk.Revit.DB.Document object at 0x000000000000002B [Autodesk.Revit.DB.Document]>
>>> 
>>> id=ElementId(322639)
>>> e=doc.GetElement(id)
>>> e.IsExternalFileReference()
False
>>> e.GetExternalFileReference()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: This Element does not represent an external file.
>>> 
>>> def f(i):
...   id=ElementId(i)
...   e=doc.GetElement(id)
...   return e.IsExternalFileReference()
...
>>> f(322639)
False
>>> f(322640)
False
>>> f(322641)
False
>>> f(322642)
False
>>> 

 

Well, at least this little exercise proves that your can very quickly indeed install and make productive use of the Revit Python shell.

 

Using the Ruby shell is equally easy.

 

I had a look at the results of calling ExternalFileUtils.GetAllExternalFileReferences as well:

 

>>> ids=ExternalFileUtils.GetAllExternalFileReferences(doc)
>>> ids
List[ElementId]([<Autodesk.Revit.DB.ElementId object at 0x000000000000002E [109330]>, <Autodesk.Revit.DB.ElementId object at 0x000000000000002F [320645]>])
>>> id=ids[0]
>>> id
<Autodesk.Revit.DB.ElementId object at 0x000000000000002E [109330]>
>>> e=doc.GetElement(id)
>>> e
<Autodesk.Revit.DB.KeynoteTable object at 0x0000000000000030 [Autodesk.Revit.DB.KeynoteTable]>
>>> 

 

That just leads to the keynote table, not the linked point cloud that we are after.

 

Anyway, to sum up, you may just have to live with the RCP filename and no path, and then see what you can achieve with that using operating system search tools.

 

Cheers,

 

Jeremy

 

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 11 of 21

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Btmsoftware,

 

After further research by myself and Revitalizer (thank you, Rudi!) I am sorry to say that we are forced to conclude that there is currently no known way to retrieve the path of the point cloud scan file.

 

I tried in Python as described above, and he explored similar paths in C# with the same results.

 

We are looking at providing this access in an updated version of the Revit API as soon as possible, though.

 

I hope this helps.

 

Best regards,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 12 of 21

btmsoftware
Advocate
Advocate

Hi Jeremy,

 

I really appreciate the extra mile on that topic. Can't wait to get the updated version

 

Thanx

 

Francois

0 Likes
Message 13 of 21

btmsoftware
Advocate
Advocate

Hi Jeremy,

 

Since this old story, I've been upgrading to 2016 (have to follow the customer's  version) but still couldn't find anything for the full path of the cloud points.

 

do you know if there's a new function I missed since 2015 and if not, do you know if there's something in Revit 2017 ?

 

TIA

 

Francois

0 Likes
Message 14 of 21

Revitalizer
Advisor
Advisor
Accepted solution

Hi,

 

a quick search in the RevitAPI.chm for 2016 says that there is a PointCloudType.GetPath() method.

May this help ?

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





Message 15 of 21

btmsoftware
Advocate
Advocate

Indeed ,from the instance I can get the type and from the type, I can get the path with this method.

 

thanx a lot (How the hell did I miss that ?)

 

Now the next step is to be able to change the source file location. If you have any idea, let me know...

 

 

0 Likes
Message 16 of 21

jeremytammik
Autodesk
Autodesk

Can you confirm that it worked?

 

Can you provide a snippet of sample code showing the sequence of calls?

 

Thank you!



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 17 of 21

btmsoftware
Advocate
Advocate

Yes, it works. I'll do the snippet next week (I'm over my head at the moment 😉

0 Likes
Message 18 of 21

Anonymous
Not applicable

n you pls provide the snipped, i can't figure a way to get PointCloud Path

0 Likes
Message 19 of 21

ajinkya.warade
Explorer
Explorer
Hi,
I came across this thread while searching to retrieve point cloud path, Im a newbie but as I followed the steps mentioned in response from Revitalizer and btmsoftware. I am able to retrieve path.

List<Element> pointcloud = new FilteredElementCollector(doc).OfClass(typeof(PointCloudType)).ToElements().ToList();
if (pointcloud.Count > 0)
{
foreach (PointCloudType point in pointcloud)
{
//returns path
ModelPath path = point.GetPath();
//convert to user readable string format.
string path_location = ModelPathUtils.ConvertModelPathToUserVisiblePath(path);
}
Message 20 of 21

jeremy_tammik
Alumni
Alumni

Thank you very much for sharing this good news and useful code snippet.

 

Just fyi, you can eliminate both the call to ToElements and to ToList.

 

Oh, and, while you're at it, the `if` statement as well.

  

This should work just as well. In fact, a tiny bit better:

 

  List<Element> pointclouds = new FilteredElementCollector(doc)
    .OfClass(typeof(PointCloudType));
    
  foreach (PointCloudType point in pointclouds)
  {
    //returns path
    ModelPath path = point.GetPath();
    //convert to user readable string format.
    string path_location = ModelPathUtils.ConvertModelPathToUserVisiblePath(path);
  }

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open