[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2051] contrib/py/scripts/addons: Initial import of io_points_pcd, importer for the point cloud data format from pcl (point cloud library).
Aurel W
aurel.w at gmail.com
Tue Jun 21 12:47:16 CEST 2011
Revision: 2051
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2051
Author: aurel
Date: 2011-06-21 10:47:15 +0000 (Tue, 21 Jun 2011)
Log Message:
-----------
Initial import of io_points_pcd, importer for the point cloud data format from pcl (point cloud library).
Added Paths:
-----------
contrib/py/scripts/addons/io_points_pcd/
contrib/py/scripts/addons/io_points_pcd/__init__.py
contrib/py/scripts/addons/io_points_pcd/pcd_utils.py
contrib/py/scripts/addons/io_points_pcd/pcdparser.py
contrib/py/scripts/addons/io_points_pcd/test.pcd
Added: contrib/py/scripts/addons/io_points_pcd/__init__.py
===================================================================
--- contrib/py/scripts/addons/io_points_pcd/__init__.py (rev 0)
+++ contrib/py/scripts/addons/io_points_pcd/__init__.py 2011-06-21 10:47:15 UTC (rev 2051)
@@ -0,0 +1,103 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+ "name": "PCD",
+ "author": "Aurel Wildfellner",
+ "version": (0, 1),
+ "blender": (2, 5, 7),
+ "api": 37304,
+ "location": "File > Import-Export > Point Cloud Data",
+ "description": "Imports and Exports PCD (Point Cloud Data) files. PCD files are the default format used by pcl (Point Cloud Library).",
+ "warning": "",
+ "wiki_url": "",
+ "tracker_url": "",
+# "support": 'OFFICAL',
+ "category": "Import-Export"}
+
+
+if "bpy" in locals():
+ import imp
+ imp.reload(pcd_utils)
+else:
+ from . import pcd_utils
+
+import itertools
+import os
+
+
+import bpy
+from bpy.props import *
+from bpy_extras.io_utils import ExportHelper, ImportHelper
+
+
+class ImportPCD(bpy.types.Operator, ImportHelper):
+ '''Load PCD (Point Cloud Data) files'''
+ bl_idname = "import_points.stl"
+ bl_label = "Import PCD"
+
+ filename_ext = ".pcd"
+
+ filter_glob = StringProperty(default="*.pcd", options={'HIDDEN'})
+
+ files = CollectionProperty(name="File Path",
+ description="File path used for importing "
+ "the PCD file",
+ type=bpy.types.OperatorFileListElement)
+
+ directory = StringProperty(subtype='DIR_PATH')
+
+ def execute(self, context):
+ paths = [os.path.join(self.directory, name.name) for name in self.files]
+ if not paths:
+ paths.append(self.filepath)
+
+ for path in paths:
+ pcd_utils.import_pcd(path)
+
+ return {'FINISHED'}
+
+
+
+
+def menu_func_import(self, context):
+ self.layout.operator(ImportPCD.bl_idname, text="Point Cloud Data (.pcd)").filepath = "*.pcd"
+
+
+def menu_func_export(self, context):
+ #self.layout.operator(ExportPLY.bl_idname, text="Point Cloud Data (.pcd)")
+ pass
+
+
+def register():
+ bpy.utils.register_module(__name__)
+
+ bpy.types.INFO_MT_file_import.append(menu_func_import)
+ bpy.types.INFO_MT_file_export.append(menu_func_export)
+
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+ bpy.types.INFO_MT_file_import.remove(menu_func_import)
+ bpy.types.INFO_MT_file_export.remove(menu_func_export)
+
+
+if __name__ == "__main__":
+ register()
+
Added: contrib/py/scripts/addons/io_points_pcd/pcd_utils.py
===================================================================
--- contrib/py/scripts/addons/io_points_pcd/pcd_utils.py (rev 0)
+++ contrib/py/scripts/addons/io_points_pcd/pcd_utils.py 2011-06-21 10:47:15 UTC (rev 2051)
@@ -0,0 +1,55 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+import bpy
+
+from . import pcdparser
+
+
+def create_and_link_mesh(name, points):
+ '''
+ Create a blender mesh and object called name from a list of
+ *points* and link it in the current scene.
+ '''
+
+ mesh = bpy.data.meshes.new(name)
+ mesh.from_pydata(points, [], [])
+
+ # update mesh to allow proper display
+ mesh.validate()
+ mesh.update()
+
+ scene = bpy.context.scene
+
+ obj = bpy.data.objects.new(name, mesh)
+ scene.objects.link(obj)
+ obj.select = True
+
+
+def import_pcd(filepath, name="new_pointcloud"):
+ parser = pcdparser.PCDParser.factory(filepath, pcdparser.PointXYZ)
+ parser.parseFile()
+ points = parser.getPoints()
+
+ blender_points = []
+ for point in points:
+ blender_points.append((point.x, point.y, point.z))
+
+ create_and_link_mesh(name, blender_points)
+
+
Added: contrib/py/scripts/addons/io_points_pcd/pcdparser.py
===================================================================
--- contrib/py/scripts/addons/io_points_pcd/pcdparser.py (rev 0)
+++ contrib/py/scripts/addons/io_points_pcd/pcdparser.py 2011-06-21 10:47:15 UTC (rev 2051)
@@ -0,0 +1,338 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+
+import struct
+
+
+def encodeASCIILine(line):
+ return line.decode(encoding='ASCII')
+
+
+
+class Point:
+
+ def __init__(self):
+ pass
+
+
+ def setField(self, fieldname, values):
+ pass
+
+
+
+
+class PointXYZ(Point):
+
+ x = 0
+ y = 0
+ z = 0
+
+ def __init__(self):
+ super().__init__()
+
+
+ def setField(self, fieldname, values):
+ value = values[0]
+ if fieldname == 'x':
+ self.x = value
+ elif fieldname == 'y':
+ self.y = value
+ elif fieldname == 'z':
+ self.z = value
+
+
+
+
+class PCDParser:
+
+ filepath = ''
+ file = None
+
+ points = []
+ PointClass = None
+
+ headerEnd = False
+
+
+ @staticmethod
+ def factory(filepath, PointClass):
+ version = 'NO_VERSION_NUMBER'
+ with open(filepath, 'rb') as f:
+ for b in f:
+ line = encodeASCIILine(b)
+ line_split = line.split()
+ if line_split[0] == 'VERSION' and len(line_split) > 1:
+ version = line_split[1]
+ break
+
+ if version == ".7" or version == "0.7":
+ return PCDParser_v0_7(filepath, PointClass)
+ else:
+ return None
+
+
+ def __init__(self, filepath, PointClass):
+ self.filepath = filepath
+ self.PointClass = PointClass
+
+ self.file = None
+ self.headerEnd = False
+ self.points = []
+
+
+ def parserWarning(self, msg):
+ print("[WARNING] ", msg)
+
+
+ def rmComment(self, line):
+ return line[:line.find('#')]
+
+
+ def parseFile(self):
+ with open(self.filepath, 'rb') as self.file:
+ self.parseHeader()
+ self.parsePoints()
+
+
+ def parseHeader(self):
+ for b in self.file:
+ line = encodeASCIILine(b)
+ line = self.rmComment(line)
+
+ split = line.split()
+ if len(split) > 0:
+ self.parseHeaderLine(split)
+
+ if self.headerEnd:
+ self.finalizeHeader()
+ break
+
+
+ def parseHeaderLine(self, split):
+ keyword = split[0]
+ self.parserWarning("Uknown header Keyword '" + keyword + "' gets ignored")
+
+
+ def finalizeHeader(self):
+ pass
+
+
+ def parsePoints(self):
+ pass
+
+
+ def getPoints(self):
+ return self.points
+
+
+ def version(self):
+ return 'NO_VERSION_NUMBER'
+
+
+
+
+class PCDParser_v0_7(PCDParser):
+
+ fields = []
+
+ def __init__(self, filepath, PointClass):
+ super().__init__(filepath, PointClass)
+ self.fields = []
+
+
+ def version(self):
+ return '.7'
+
+
+ def parseHeaderLine(self, split):
+ keyword = split[0]
+ if keyword == 'VERSION':
+ self.parseVERSION(split[1:])
+ elif keyword == 'FIELDS':
+ self.parseFIELDS(split[1:])
+ elif keyword == 'SIZE':
+ self.parseSIZE(split[1:])
+ elif keyword == 'TYPE':
+ self.parseTYPE(split[1:])
+ elif keyword == 'COUNT':
+ self.parseCOUNT(split[1:])
+ elif keyword == 'WIDTH':
+ self.parseWIDTH(split[1:])
+ elif keyword == 'HEIGHT':
+ self.parseHEIGHT(split[1:])
+ elif keyword == 'POINTS':
+ self.parsePOINTS(split[1:])
+ elif keyword == 'DATA':
+ self.parseDATA(split[1:])
+ else:
+ super().parseHeaderLine(split)
+
+
+ def parseVERSION(self, split):
+ pass
+
+
+ def parseFIELDS(self, split):
+ print("SPLIT FIELDS:", split)
+ for field in split:
+ self.fields.append([field, None, None, None])
+ print("FIELDS, after parsing:", self.fields)
+
+
+ def parseSIZE(self, split):
+ for i, size in enumerate(split):
+ self.fields[i][1] = int(size)
+
+
+ def parseTYPE(self, split):
+ for i, type in enumerate(split):
+ self.fields[i][2] = type
+
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list