def process_file(base_dir, f): current_process().daemon = False base_name = decode(f['base_name']) full_path = decode(f['full_path']) zip_hash = decode(f['metadata']['types']['original']['zip']) f_dir = full_path.replace('/', '_') f_dir = os.path.join(base_dir, f_dir) if not os.path.isdir(f_dir): os.mkdir(f_dir) orig_zip = os.path.join(f_dir, base_name + '.orig.zip') if not os.path.isfile(orig_zip): f_data = urllib2.urlopen(DOWNLOAD + '/' + zip_hash).read() orig_zip_file = open(orig_zip, 'wb') orig_zip_file.write(f_data) orig_zip_file.close() optimizations = factory.getInstance('full_optimizations') save = factory.getInstance('save_collada_zip') orig_ss = orig_zip + '.png' opt_zip = os.path.join(f_dir, base_name + '.opt.zip') opt_ss = opt_zip + '.png' mesh = collada.Collada(orig_zip, zip_filename=base_name) orig_render_info = getRenderInfo(mesh) if not os.path.isfile(orig_ss): p = Process(target=save_screenshot, args=(orig_zip, orig_ss), kwargs={'zip_filename': base_name}) p.start() p.join() if not os.path.isfile(opt_zip): optimizations.apply(mesh) save.apply(mesh, opt_zip) mesh = None optmesh = collada.Collada(opt_zip) opt_render_info = getRenderInfo(optmesh) optmesh = None if not os.path.isfile(opt_ss): p = Process(target=save_screenshot, args=(opt_zip, opt_ss)) p.start() p.join() orig_ss_copy = f_dir + '.orig.png' opt_ss_copy = f_dir + '.opt.png' if not os.path.isfile(orig_ss_copy): shutil.copy2(orig_ss, orig_ss_copy) if not os.path.isfile(opt_ss_copy): shutil.copy2(opt_ss, opt_ss_copy) orig_size = os.stat(orig_zip)[6] opt_size = os.stat(opt_zip)[6] return (f_dir, orig_size, opt_size, orig_render_info, opt_render_info)
def test_collada_duck_poly(self): f = os.path.join(self.datadir, "duck_polylist.dae") mesh = collada.Collada(f, validate_output=True) self.assertEqual(mesh.scene.id, 'VisualSceneNode') self.assertIn('LOD3spShape-lib', mesh.geometries) self.assertIn('directionalLightShape1-lib', mesh.lights) self.assertIn('cameraShape1', mesh.cameras) self.assertIn('file2', mesh.images) self.assertIn('blinn3-fx', mesh.effects) self.assertIn('blinn3', mesh.materials) self.assertEqual(len(mesh.nodes), 0) self.assertIn('VisualSceneNode', mesh.scenes) s = BytesIO() mesh.write(s) out = s.getvalue() t = BytesIO(out) mesh = collada.Collada(t, validate_output=True) self.assertEqual(mesh.scene.id, 'VisualSceneNode') self.assertIn('LOD3spShape-lib', mesh.geometries) self.assertIn('directionalLightShape1-lib', mesh.lights) self.assertIn('cameraShape1', mesh.cameras) self.assertIn('file2', mesh.images) self.assertIn('blinn3-fx', mesh.effects) self.assertIn('blinn3', mesh.materials) self.assertEqual(len(mesh.nodes), 0) self.assertIn('VisualSceneNode', mesh.scenes)
def read(self, f, assethandler=None, submesh=None, options=None): ''' Read collada model data given the file path ''' self._basepath = os.path.dirname(f) self._assethandler = assethandler try: d = collada.Collada(f) except: # workaround for pycollada's handling of xml comments xdoc = lxml.etree.parse(f) for c in xdoc.xpath('//comment()'): p = c.getparent() p.remove(c) try: d = collada.Collada(StringIO(lxml.etree.tostring(xdoc))) except: logging.error("error while processing %s" % f) raise for m in d.materials: mm = model.MaterialModel() mm.name = m.id if type(m.effect.diffuse) == collada.material.Map: fname = os.path.abspath( os.path.join(self._basepath, m.effect.diffuse.sampler.surface.image.path)) if not os.path.exists(fname): if fname.count('/meshes/') > 0: fname = fname.replace('/meshes/', '/materials/textures/') if self._assethandler: mm.texture = self._assethandler(fname) else: mm.texture = fname elif m.effect.diffuse is not None: mm.diffuse = m.effect.diffuse self._materials[mm.name] = mm m = model.MeshTransformData() unitmeter = d.assetInfo.unitmeter if unitmeter == None: unitmeter = 1.0 logging.info("unitmeter is not specified in dae and 1.0 is used.") m.matrix = tf.scale_matrix(unitmeter) m.children = [] rootnodes = d.scene.nodes if submesh is not None: for n in d.scene.nodes: trans = model.TransformationModel() trans.matrix = numpy.identity(4) f = self.findchild(n, submesh, trans) f = self.filterchild(f, submesh) if f is not None: rootnodes = [f] break for n in rootnodes: cm = self.convertchild(n) if cm is not None: m.children.append(cm) return m
def read(farm_boy_model_path: Path) -> Model: ''' Read a collada file. When reading a collada file we need to extract data about two main parts of the model - the mesh and the skeleton. We can also extract animation data. The mesh data includes the vertices, texture_coords and normals. It also includes the indices. The skeleton data includes information about the skeleton of the model - the joints, their hierarchy, transformation matrices (local bind transform, inverse bind transform); also, for each vertex we have the joints that affect it and the respective weights (used for LBS). The animation data mainly includes the key frames. ''' ext = farm_boy_model_path.suffix.lower() if ext != '.dae': print("Please use only .dae files. Exiting...") raise SystemExit model_data = collada.Collada(farm_boy_model_path.as_posix()) data = _read_model_data(model_data) model = Model(faces=data["faces"], vertices=data["vertices"], vertex_texture_coords=data["vertex_texture_coords"], vertex_normals=data["vertex_normals"], root_joint=data["root_joint"], vertex_joints=data["vertex_joints"], vertex_joints_weights=data["vertex_joints_weights"], animation=Animation(data["key_frames"])) return model
def __init__(self, model_path): ext = splitext(model_path)[1].lower() if ext != '.dae': print("Please use only .dae files. Exiting...") raise SystemExit self.model_data = collada.Collada(model_path) # vertices, indices, texture_coords = self.__parse_model_data() indices, vertices, texture_coords, vertex_joints, weights, root_joint, key_frames = self.__parse_model_data_no_texture() normals = np.zeros(len(vertices)) self.indices = indices.astype('int32') self.vertices = vertices.astype('float32') self.texture_coords = texture_coords.astype('float32') self.normals = normals.astype('float32') self.vertex_joints = vertex_joints.astype('int32') self.weights = weights.astype('float32') assert self.indices.max()+1 == len(self.vertices) // 3 == len(self.texture_coords) // 2 == len( self.normals) // 3 == len(self.vertex_joints) // 3 == len(self.weights) // 3 self.root_joint: Joint = root_joint self.key_frames = key_frames print(self.root_joint) return
def run(self): sys = self.getData("sys") cmp = Component() cmp = sys.addComponent(cmp, self.object) print self.FileName col = collada.Collada( self.FileName, ignore=[collada.DaeUnsupportedError, collada.DaeBrokenRefError]) for geom in col.geometries: for triset in geom.primitives: trilist = list(triset) elements = len(trilist) for i in range(elements): nl = nodevector() for j in range(3): node = triset.vertex[triset.vertex_index][i][j] n = sys.addNode( float(node[0] * self.ScaleX + self.OffsetX), float(node[1] * self.ScaleY + self.OffsetY), float(node[2]) * self.ScaleZ) nl.append(n) nl.append(nl[0]) f = sys.addFace(nl, self.geometry) cmp.getAttribute("Geometry").setLink( "Geometry", f.getUUID())
def read(filename): global col col = collada.Collada(filename, ignore=[collada.DaeUnsupportedError]) # Read the unitmeter info from dae file and compute unit to convert to mm unitmeter = col.assetInfo.unitmeter or 1 unit = unitmeter / 0.001 for geom in col.scene.objects('geometry'): #for geom in col.geometries: for prim in geom.primitives(): #for prim in geom.primitives: #print prim, dir(prim) meshdata = [] if hasattr(prim, "triangles"): tset = prim.triangles() elif hasattr(prim, "triangleset"): tset = prim.triangleset() for tri in tset: face = [] for v in tri.vertices: v = [x * unit for x in v] face.append([v[0], v[1], v[2]]) meshdata.append(face) #print meshdata newmesh = Mesh.Mesh(meshdata) #print newmesh obj = FreeCAD.ActiveDocument.addObject("Mesh::Feature", "Mesh") obj.Mesh = newmesh
def test_collada_attribute_replace(self): mesh = collada.Collada(validate_output=True) self.assertIsInstance(mesh.geometries, collada.util.IndexedList) self.assertIsInstance(mesh.controllers, collada.util.IndexedList) self.assertIsInstance(mesh.animations, collada.util.IndexedList) self.assertIsInstance(mesh.lights, collada.util.IndexedList) self.assertIsInstance(mesh.cameras, collada.util.IndexedList) self.assertIsInstance(mesh.images, collada.util.IndexedList) self.assertIsInstance(mesh.effects, collada.util.IndexedList) self.assertIsInstance(mesh.materials, collada.util.IndexedList) self.assertIsInstance(mesh.nodes, collada.util.IndexedList) self.assertIsInstance(mesh.scenes, collada.util.IndexedList) mesh.geometries = [] mesh.controllers = [] mesh.animations = [] mesh.lights = [] mesh.cameras = [] mesh.images = [] mesh.effects = [] mesh.materials = [] mesh.nodes = [] mesh.scenes = [] self.assertIsInstance(mesh.geometries, collada.util.IndexedList) self.assertIsInstance(mesh.controllers, collada.util.IndexedList) self.assertIsInstance(mesh.animations, collada.util.IndexedList) self.assertIsInstance(mesh.lights, collada.util.IndexedList) self.assertIsInstance(mesh.cameras, collada.util.IndexedList) self.assertIsInstance(mesh.images, collada.util.IndexedList) self.assertIsInstance(mesh.effects, collada.util.IndexedList) self.assertIsInstance(mesh.materials, collada.util.IndexedList) self.assertIsInstance(mesh.nodes, collada.util.IndexedList) self.assertIsInstance(mesh.scenes, collada.util.IndexedList)
def _shape(self): shapes = [] c = collada.Collada(self.path) for g in c.geometries: for p in g.primitives: if not isinstance(p, collada.lineset.LineSet): fields = {} fields['geometry'] = self._indexed_face_set(p) if p.material: material = c.materials[p.material] if material and material.effect: appearance = self._appearance(material.effect) fields['appearance'] = appearance shapes.append(Node('Shape', fields)) if len(shapes) == 1: return shapes[0] return Node('Group', { 'children': shapes })
def export_mesh(vertices, triangles, filename, mesh_name="mcubes_mesh"): """ Exports a mesh in the COLLADA (.dae) format. Needs PyCollada (https://github.com/pycollada/pycollada). """ import collada mesh = collada.Collada() vert_src = collada.source.FloatSource("verts-array", vertices, ('X', 'Y', 'Z')) geom = collada.geometry.Geometry(mesh, "geometry0", mesh_name, [vert_src]) input_list = collada.source.InputList() input_list.addInput(0, 'VERTEX', "#verts-array") triset = geom.createTriangleSet(np.copy(triangles), input_list, "") geom.primitives.append(triset) mesh.geometries.append(geom) geomnode = collada.scene.GeometryNode(geom, []) node = collada.scene.Node(mesh_name, children=[geomnode]) myscene = collada.scene.Scene("mcubes_scene", [node]) mesh.scenes.append(myscene) mesh.scene = myscene mesh.write(filename)
def __init__(self, inFileName): # inputFilename = sys.argv[1] col = collada.Collada( inFileName, ignore=[collada.DaeUnsupportedError, collada.DaeBrokenRefError]) if col.scene is not None: for geom in col.scene.objects('geometry'): for prim in geom.primitives(): # use primitive-specific ways to get triangles prim_type = type(prim).__name__ if prim_type == 'BoundTriangleSet': triangles = prim elif prim_type == 'BoundPolylist': triangles = prim.triangleset() else: print 'Unsupported mesh used:', prim_type triangles = None if triangles is not None: # # triangles.generateNormals() vertices = triangles.vertex #.flatten().tolist() vertex_indices = triangles.vertex_index #.flatten().tolist() VERTICES = vertices[vertex_indices] normals = triangles.normal normal_indices = triangles.normal_index # .flatten().tolist() NORMALS = normals[normal_indices] uv = triangles.texcoordset[0] uv_indices = triangles.texcoord_indexset[0] UV = uv[uv_indices] x1 = VERTICES[:, 1, 0] - VERTICES[:, 0, 0] x2 = VERTICES[:, 2, 0] - VERTICES[:, 0, 0] y1 = VERTICES[:, 1, 1] - VERTICES[:, 0, 1] y2 = VERTICES[:, 2, 1] - VERTICES[:, 0, 1] z1 = VERTICES[:, 1, 2] - VERTICES[:, 0, 2] z2 = VERTICES[:, 2, 2] - VERTICES[:, 0, 2] s1 = UV[:, 1, 0] - UV[:, 0, 0] s2 = UV[:, 2, 0] - UV[:, 0, 0] t1 = UV[:, 1, 1] - UV[:, 0, 1] t2 = UV[:, 2, 1] - UV[:, 0, 1] f = 1.0 / (s1 * t2 - s2 * t1) tanX = (x1 * t2 - x2 * t1) * f tanY = (y1 * t2 - y2 * t1) * f tanZ = (z1 * t2 - z2 * t1) * f tangent = numpy.vstack((tanX, tanY, tanZ)).T TANGENTS = normalize_v3( tangent) # one tangent for triangle face BINORMALS = numpy.cross( NORMALS, tangent) # one BINORMALS for triangle face self.VERTICES = VERTICES self.NORMALS = NORMALS self.UV = UV self.TANGENTS = TANGENTS self.BINORMALS = BINORMALS
def get_collada_data(self): if self._cached_collada_data is not None: collada_data = self._cached_collada_data else: collada_data = collada.Collada(self.filesystem_path) self._cached_collada_data = collada_data return collada_data
def main(): mesh = collada.Collada(f'{name}.dae') geom = mesh.geometries[0] triset = geom.primitives[0] # TODO: Read pycollada docs, this is probably tremendously inefficient pos_set = triset.sources['VERTEX'][0][4] normal_set = triset.sources['NORMAL'][0][4] tex_set = triset.sources['TEXCOORD'][0][4] color_set = triset.sources['COLOR'][0][4] vert_dict = {} for t in triset.indices: for v in t: vert_dict[v[0]] = (v[1], v[2], v[3]) #print(f'Pos: {pos_set[0]}') #print(f'Normal: {normal_set[vert_dict[0][0]]}') #print(f'Tex: {tex_set[vert_dict[0][1]]}') #print(f'Color: {color_set[vert_dict[0][2]]}') # Write vertices to file with open(f'{name}-out.bin', 'wb') as f: for i in range(0, len(pos_set)): x = pos_set[i][0] y = pos_set[i][1] z = pos_set[i][2] a = normal_set[vert_dict[i][0]][0] b = normal_set[vert_dict[i][0]][1] c = normal_set[vert_dict[i][0]][2] f.write(struct.pack('<6f', x, y, z, a, b, c)) if vert_mode == 36: r = int(color_set[vert_dict[0][2]][0] * 255) g = int(color_set[vert_dict[0][2]][1] * 255) b = int(color_set[vert_dict[0][2]][2] * 255) f.write(struct.pack('<BBBB', r, g, b, 255)) u = tex_set[vert_dict[i][1]][0] v = 1.0 - tex_set[vert_dict[i][1]][1] f.write(struct.pack('<2f', u, v)) # Stripify and write index buffer to file trilist = [] for face in triset.indices: #INVERTED WINDING ORDER trilist.append((int(face[2][0]), int(face[1][0]), int(face[0][0]))) stripped = tristrip.stripify(trilist, True)[0] print(len(stripped)) with open(f'{name}-ibuf.txt', 'w') as f: f.write('1\n') f.write('1\n') f.write(f'{len(stripped)}\n') for i in stripped: f.write(f'{i} ') f.write('\n')
def _build_graph(self): col = collada.Collada(self._graph_collada_fname) geom = col.geometries[0] lineset = geom.primitives[0] self._graph = defaultdict(set) for node1, node2 in lineset.vertex_index: self._graph[node1].add(node2) self._points = lineset.vertex
def check_large(files): dae = collada.Collada(files) alltriangles = np.vstack([ i.vertex[i.vertex_index] for j in dae.scene.objects('geometry') for i in j.primitives() if isinstance(i, collada.triangleset.BoundTriangleSet) ]) print(files, alltriangles.shape)
def apply(self, filename): if not os.path.isfile(filename): raise FilterException("argument is not a valid file") try: col = collada.Collada(filename) except collada.DaeError, e: print e raise FilterException("errors while loading file")
def test_should_find_commented_objects_in_mesh(self): #file = open('./test_resources/3wall.dae') file = open('./test_resources/blue_house.dae') collada_data = collada.Collada(file) for item in collada_data.scene.nodes: for child in item.children: self.assertEqual('ID2', child.id)
def export(exportList,filename,tessellation=1): "called when freecad exports a file" if not checkCollada(): return p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") scale = p.GetFloat("ColladaScalingFactor",1.0) colmesh = collada.Collada() colmesh.assetInfo.upaxis = collada.asset.UP_AXIS.Z_UP effect = collada.material.Effect("effect0", [], "phong", diffuse=(.7,.7,.7), specular=(1,1,1)) mat = collada.material.Material("material0", "mymaterial", effect) colmesh.effects.append(effect) colmesh.materials.append(mat) objind = 0 scenenodes = [] objectslist = Draft.getGroupContents(exportList,walls=True,addgroups=True) objectslist = Arch.pruneIncluded(objectslist) for obj in objectslist: vindex = [] nindex = [] findex = [] m = None if obj.isDerivedFrom("Part::Feature"): print "exporting object ",obj.Name, obj.Shape m = Mesh.Mesh(triangulate(obj.Shape)) elif obj.isDerivedFrom("Mesh::Feature"): print "exporting object ",obj.Name, obj.Mesh m = obj.Mesh if m: # vertex indices for v in m.Topology[0]: vindex.extend([v.x*scale,v.y*scale,v.z*scale]) # normals for f in m.Facets: n = f.Normal nindex.extend([n.x,n.y,n.z]) # face indices for i in range(len(m.Topology[1])): f = m.Topology[1][i] findex.extend([f[0],i,f[1],i,f[2],i]) print len(vindex), " vert indices, ", len(nindex), " norm indices, ", len(findex), " face indices." vert_src = collada.source.FloatSource("cubeverts-array"+str(objind), numpy.array(vindex), ('X', 'Y', 'Z')) normal_src = collada.source.FloatSource("cubenormals-array"+str(objind), numpy.array(nindex), ('X', 'Y', 'Z')) geom = collada.geometry.Geometry(colmesh, "geometry"+str(objind), obj.Name, [vert_src, normal_src]) input_list = collada.source.InputList() input_list.addInput(0, 'VERTEX', "#cubeverts-array"+str(objind)) input_list.addInput(1, 'NORMAL', "#cubenormals-array"+str(objind)) triset = geom.createTriangleSet(numpy.array(findex), input_list, "materialref") geom.primitives.append(triset) colmesh.geometries.append(geom) matnode = collada.scene.MaterialNode("materialref", mat, inputs=[]) geomnode = collada.scene.GeometryNode(geom, [matnode]) node = collada.scene.Node("node"+str(objind), children=[geomnode]) scenenodes.append(node) objind += 1 myscene = collada.scene.Scene("myscene", scenenodes) colmesh.scenes.append(myscene) colmesh.scene = myscene colmesh.write(filename) FreeCAD.Console.PrintMessage(translate("Arch","file %s successfully created.") % filename)
def merge_dae_files(list_fpath_inputs, fpath_output, scene_name="myscene"): list_dae_objects = [] for fpath_input in list_fpath_inputs: list_dae_objects.append(dae.Collada(fpath_input)) merged_dae_object = merge_dae_objects(list_dae_objects, scene_name="myscene") merged_dae_object.write(fpath_output)
def get_stlstr(binary=1, _self=cmd): ''' DESCRIPTION STL geometry export ''' import collada import io import struct _self.set('cartoon_loop_cap', 2) _self.set('stick_round_nub', 2) _self.set('collada_geometry_mode', 1) daestring = _self.get_collada() daestream = io.BytesIO(daestring.encode('utf-8')) mesh = collada.Collada(daestream, [ collada.common.DaeUnsupportedError, collada.common.DaeBrokenRefError, ]) if binary: bout = [b' ' * 80, None] else: aout = ['solid x'] for geom in mesh.geometries: for prim in geom.primitives: for t in prim: N = len(t.vertices) for i0 in range(0, N - 1, 2): triangle = [t.vertices[i % N] for i in range(i0, i0 + 3)] if binary: bout.append(struct.pack('<fff', *t.normals[i0])) for vertex in triangle: bout.append(struct.pack('<fff', *vertex)) bout.append(struct.pack('<H', 0)) # Attribute byte count else: aout.append('facet normal %f %f %f' % tuple(t.normals[i0])) aout.append('outer loop') for vertex in triangle: aout.append('vertex %f %f %f' % tuple(vertex)) aout.append('endloop') aout.append('endfacet') if binary: bout[1] = struct.pack('<I', (len(bout) - 2) // 5) return b''.join(bout) aout.append('endsolid x') aout.append('') return '\n'.join(aout)
def write(self, m, f, options=None): ''' Write simulation model in collada format ''' # we use pycollada to generate the dae file self._mesh = collada.Collada() # create effect and material if m.data.material: if m.data.material.texture: image = collada.material.CImage("material0-image", m.data.material.texture) surface = collada.material.Surface("material0-image-surface", image) sampler2d = collada.material.Sampler2D( "material0-image-sampler", surface) map1 = collada.material.Map(sampler2d, "UVSET0") effect = collada.material.Effect("effect0", [surface, sampler2d], "lambert", emission=(0.0, 0.0, 0.0, 1), ambient=(0.0, 0.0, 0.0, 1), diffuse=map1, transparency=0.0, double_sided=True) self._mesh.images.append(image) else: effect = collada.material.Effect( "effect0", [], "phong", double_sided=True, diffuse=m.data.material.diffuse, specular=m.data.material.specular, index_of_refraction=1.0) else: effect = collada.material.Effect("effect0", [], "phong", double_sided=True, diffuse=(0.8, 0.8, 0.8), specular=(1, 1, 1), index_of_refraction=1.0) mat = collada.material.Material("material0", "mymaterial", effect) self._mesh.effects.append(effect) self._mesh.materials.append(mat) self._matnode = collada.scene.MaterialNode("materialref", mat, inputs=[]) # convert shapes recursively node = collada.scene.Node("root", children=[self.convertchild(m.data)]) # create scene graph myscene = collada.scene.Scene("myscene", [node]) self._mesh.scenes.append(myscene) self._mesh.scene = myscene self._mesh.write(f)
def read(filename): "reads a DAE file" global col col = collada.Collada(filename, ignore=[collada.DaeUnsupportedError]) # Read the unitmeter info from dae file and compute unit to convert to mm unitmeter = col.assetInfo.unitmeter or 1 unit = unitmeter / 0.001 #for geom in col.geometries: #for geom in col.scene.objects('geometry'): for node in col.scene.nodes: if list(node.objects("geometry")): color = None # retrieving material if "}" in node.xmlnode.tag: bt = node.xmlnode.tag.split("}")[0] + "}" gnode = node.xmlnode.find(bt + "instance_geometry") if gnode is not None: bnode = gnode.find(bt + "bind_material") if bnode is not None: tnode = bnode.find(bt + "technique_common") if tnode is not None: mnode = tnode.find(bt + "instance_material") if mnode is not None: if "target" in mnode.keys(): mname = mnode.get("target").strip("#") for m in col.materials: if m.id == mname: e = m.effect if isinstance(e.diffuse, tuple): color = e.diffuse for geom in node.objects("geometry"): for prim in geom.primitives(): #print(prim, dir(prim)) meshdata = [] if hasattr(prim, "triangles"): tset = prim.triangles() elif hasattr(prim, "triangleset"): tset = prim.triangleset() else: tset = [] for tri in tset: face = [] for v in tri.vertices: v = [x * unit for x in v] face.append([v[0], v[1], v[2]]) meshdata.append(face) #print(meshdata) newmesh = Mesh.Mesh(meshdata) #print(newmesh) obj = FreeCAD.ActiveDocument.addObject( "Mesh::Feature", "Mesh") obj.Mesh = newmesh if color and FreeCAD.GuiUp: obj.ViewObject.ShapeColor = color
def write_collada(vertices, normals, triangle_indices, fname): vertices = np.array(vertices) normals = np.array(normals) triangle_indices = np.array(triangle_indices, dtype=np.int32) for i in xrange(triangle_indices.shape[0]): k1, k2, k3 = triangle_indices[i, :] x, y, z = vertices[k1], vertices[k2], vertices[k3] nx = normals[k1] if np.dot(np.cross(y - x, x - z), nx) < 0: triangle_indices[i, :] = np.array([k3, k2, k1], dtype=np.int32) assert len(vertices.shape) == 2 and vertices.shape[1] == 3 assert vertices.shape == normals.shape assert len(triangle_indices.shape) == 2 and triangle_indices.shape[1] == 3 mesh = collada.Collada() effect = collada.material.Effect("effect0", [], "phong", diffuse=(1, 0, 0), specular=(0, 1, 0)) mat = collada.material.Material("material0", "mymaterial", effect) mesh.effects.append(effect) mesh.materials.append(mat) vert_floats = vertices.flatten() normal_floats = normals.flatten() vert_src = collada.source.FloatSource("cubeverts-array", np.array(vert_floats), ('X', 'Y', 'Z')) normal_src = collada.source.FloatSource("cubenormals-array", np.array(normal_floats), ('X', 'Y', 'Z')) geom = collada.geometry.Geometry(mesh, "geometry0", "mycube", [vert_src, normal_src]) input_list = collada.source.InputList() input_list.addInput(0, 'VERTEX', "#cubeverts-array") input_list.addInput(1, 'NORMAL', "#cubenormals-array") indices = np.hstack([triangle_indices, triangle_indices]).flatten() triset = geom.createTriangleSet(indices, input_list, "materialref") geom.primitives.append(triset) mesh.geometries.append(geom) matnode = collada.scene.MaterialNode("materialref", mat, inputs=[]) geomnode = collada.scene.GeometryNode(geom, [matnode]) node = collada.scene.Node("node0", children=[geomnode]) myscene = collada.scene.Scene("myscene", [node]) mesh.scenes.append(myscene) mesh.scene = myscene mesh.write(fname)
def setUp(self): self.dummy = collada.Collada(aux_file_loader = self.image_dummy_loader, validate_output=True) self.dummy_cimage = collada.material.CImage("yourcimage", "./whatever.tga", self.dummy) self.cimage = collada.material.CImage("mycimage", "./whatever.tga", self.dummy) self.dummy.images.append(self.dummy_cimage) self.dummy.images.append(self.cimage) self.othereffect = collada.material.Effect("othereffect", [], "phong") self.dummy.effects.append(self.othereffect)
def generate_ground_plane(): mesh = collada.Collada() geom, id = generate_geometry(mesh, [100, 100, .1], [0, 0, .05, 0, 0, 0]) mesh.geometries.append(geom) geomnode = collada.scene.GeometryNode(geom) node = collada.scene.Node('node' + id, children=[geomnode]) scene = collada.scene.Scene('scene' + id, [node]) mesh.scenes.append(scene) mesh.scene = scene return [mesh]
def test_triangle_iterator_vert_normals(self): mesh = collada.Collada(validate_output=True) vert_floats = [-50, 50, 50, 50, 50, 50, -50, -50, 50, 50, -50, 50, -50, 50, -50, 50, 50, -50, -50, -50, -50, 50, -50, -50] normal_floats = [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1] vert_src = collada.source.FloatSource( "cubeverts-array", numpy.array(vert_floats), ('X', 'Y', 'Z')) normal_src = collada.source.FloatSource( "cubenormals-array", numpy.array(normal_floats), ('X', 'Y', 'Z')) geometry = collada.geometry.Geometry( mesh, "geometry0", "mycube", [ vert_src, normal_src], []) input_list = collada.source.InputList() input_list.addInput(0, 'VERTEX', "#cubeverts-array") input_list.addInput(1, 'NORMAL', "#cubenormals-array") indices = numpy.array([0, 0, 2, 1, 3, 2, 0, 0, 3, 2, 1, 3, 0, 4, 1, 5, 5, 6, 0, 4, 5, 6, 4, 7, 6, 8, 7, 9, 3, 10, 6, 8, 3, 10, 2, 11, 0, 12, 4, 13, 6, 14, 0, 12, 6, 14, 2, 15, 3, 16, 7, 17, 5, 18, 3, 16, 5, 18, 1, 19, 5, 20, 7, 21, 6, 22, 5, 20, 6, 22, 4, 23]) triangleset = geometry.createTriangleSet( indices, input_list, "cubematerial") geometry.primitives.append(triangleset) mesh.geometries.append(geometry) geomnode = collada.scene.GeometryNode(geometry, []) mynode = collada.scene.Node( 'mynode6', children=[geomnode], transforms=[]) scene = collada.scene.Scene('myscene', [mynode]) mesh.scenes.append(scene) mesh.scene = scene mesh.save() geoms = list(mesh.scene.objects('geometry')) self.assertEqual(len(geoms), 1) prims = list(geoms[0].primitives()) self.assertEqual(len(prims), 1) tris = list(prims[0]) self.assertEqual(len(tris), 12) self.assertEqual(list(tris[0].vertices[0]), [-50.0, 50.0, 50.0]) self.assertEqual(list(tris[0].vertices[1]), [-50.0, -50.0, 50.0]) self.assertEqual(list(tris[0].vertices[2]), [50.0, -50.0, 50.0]) self.assertEqual(list(tris[0].normals[0]), [0.0, 0.0, 1.0]) self.assertEqual(list(tris[0].normals[1]), [0.0, 0.0, 1.0]) self.assertEqual(list(tris[0].normals[2]), [0.0, 0.0, 1.0]) self.assertEqual(tris[0].texcoords, []) self.assertEqual(tris[0].material, None) self.assertEqual(list(tris[0].indices), [0, 2, 3]) self.assertEqual(list(tris[0].normal_indices), [0, 1, 2]) self.assertEqual(tris[0].texcoord_indices, [])
def fv_scalar_to_collada(verts, faces, scalars): # color = color_func(scalars) a = (scalars - np.min(scalars)) / (np.max(scalars) - np.min(scalars)) * 256 color = cm.jet(a.astype(int)) color = np.delete(color, 3, 1) #create collada obj mesh = collada.Collada() #add shading effect = collada.material.Effect("effect0",\ [], #TEXTURES GO HERE "phong", diffuse=(1,1,1), specular=(1,1,1), double_sided=True) mat = collada.material.Material("material0", "mymaterial", effect) mesh.effects.append(effect) mesh.materials.append(mat) vert_src = collada.source.FloatSource("verts-array", verts, ('X', 'Y', 'Z')) color_src = collada.source.FloatSource("colors-array", np.array(color), ('R', 'G', 'B')) geom = collada.geometry.Geometry(mesh, "geometry0", "fsave_test",\ [vert_src,color_src]) #creates list of inputs for collada DOM obj...so many decorators input_list = collada.source.InputList() input_list.addInput(0, 'VERTEX', "#verts-array") input_list.addInput(1, 'COLOR', "#colors-array") #creates faces triset = geom.createTriangleSet( np.concatenate([faces,faces],axis=1),\ input_list, "materialref") triset.generateNormals() geom.primitives.append(triset) mesh.geometries.append(geom) #creates scene node, which causes display matnode = collada.scene.MaterialNode("materialref", mat, inputs=[]) geomnode = collada.scene.GeometryNode(geom, [matnode]) node = collada.scene.Node("node0", children=[geomnode]) #create scene myscene = collada.scene.Scene("fs_base_scene", [node]) mesh.scenes.append(myscene) mesh.scene = myscene buf = io.BytesIO() mesh.write(buf) return buf
def getInertia(geometry, m, s): print("\033[97m Link name: \033[0m" + link_name) print("\033[93m Mass: \033[0m" + str(m)) print("\033[95m Scale: \033[0m" + str(s)) xx = yy = zz = 0.0 if type(geometry) == Mesh: print("\033[94m Mesh: \033[0m" + geometry.filename) print("---\nCalculating inertia...\n---") ROS_VERSION = os.getenv("ROS_VERSION") get_pkg_fn = None if not ROS_VERSION: print("Could not find the ROS_VERSION environment variable, thus, can't determine your ros version. Assuming ROS2!") ROS_VERSION = "2" if ROS_VERSION == "1": import rospkg get_pkg_fn = rospkg.RosPack().get_path else: import ament_index_python get_pkg_fn = ament_index_python.get_package_share_path pkg_tag = "package://" file_tag = "file://" mesh_file = "" if geometry.filename.startswith(pkg_tag): package, mesh_file = geometry.filename.split(pkg_tag)[1].split(os.sep, 1) print(get_pkg_fn(package)) mesh_file = str(get_pkg_fn(package))+os.sep+mesh_file elif geometry.filename.startswith(file_tag): mesh_file = geometry.filename.replace(file_tag, "") x = y = z = 0 if mesh_file.endswith(".stl"): model = mesh.Mesh.from_file(mesh_file) x,y,z = getSTLDimensions(model) # Assuming .dae else: model = collada.Collada(mesh_file) x,y,z = getColladaDimensions(model) xx,yy,zz = getBoxInertia(x, y, z, m, s) elif type(geometry) == Box: print("\033[94m Box: \033[0m" + str(geometry.size)) print("---\nCalculating inertia...\n---") x,y,z = geometry.size xx,yy,zz = getBoxInertia(x, y, z, m, s) elif type(geometry) == Sphere: print("\033[94m Sphere Radius: \033[0m" + str(geometry.radius)) print("---\nCalculating inertia...\n---") xx,yy,zz = getSphereInertia(geometry.radius, m) elif type(geometry) == Cylinder: print("\033[94m Cylinder Radius and Length: \033[0m" + str(geometry.radius) + "," + str(geometry.length)) print("---\nCalculating inertia...\n---") xx,yy,zz = getCylinderInertia(geometry.radius, geometry.length, m) print("\033[92m") print("<inertia ixx=\"%s\" ixy=\"0\" ixz=\"0\" iyy=\"%s\" iyz=\"0\" izz=\"%s\" />" % (xx,yy,zz)) print("\033[0m")
def __init__(self, model_part, collada_filename, import_normals=False): self.model_part = model_part self.collada_filename = str(collada_filename) self.import_normals = import_normals #open and import the collada collada_file print("attempting to open ", self.collada_filename) f = open(self.collada_filename, 'rb') self.collada_mesh = collada.Collada(f) f.close()
def export_collada(self): # not yet working import collada mesh = collada.Collada() effect = collada.material.Effect("effect0", [], "phong", diffuse=(1, 0, 0), specular=(0, 1, 0)) mat = collada.material.Material("material0", "mymaterial", effect) mesh.effects.append(effect) mesh.materials.append(mat)