def import_obj(mdlobj, obj_mat, reg_mat, add_to_model_objects=True): """ Create a new Blender mesh object. Currently, this is used by both the swig and pyparsing based importers. In addition to creating a new mesh object, a red material is applied to all surface regions and a gray material is applied to the rest of the mesh. """ meshes = bpy.data.meshes objs = bpy.data.objects scn = bpy.context.scene scn_objs = scn.objects objname = mdlobj.name print(objname, len(mdlobj.vertices), len(mdlobj.faces)) obj = objs.get(objname) # Overwrite existing object if it has the same name as the object we are # trying to import if obj: scn.objects.unlink(obj) objs.remove(obj) mesh = meshes.new(objname) mesh.from_pydata(mdlobj.vertices, [], mdlobj.faces) mesh.materials.append(obj_mat) mesh.materials.append(reg_mat) obj = objs.new(objname, mesh) scn_objs.link(obj) # Object needs to be active to add a region to it because of how # init_region (called by add_region_by_name) works. scn.objects.active = obj all_regions = [] for reg_name, regions in mdlobj.regions.items(): obj.mcell.regions.add_region_by_name(bpy.context, reg_name) reg = obj.mcell.regions.region_list[reg_name] reg.set_region_faces(obj.data, regions.faces) all_regions.extend(regions.faces) # Get list of face indices face_list = [0] * len(mesh.polygons) mesh.polygons.foreach_get('index', face_list) # Create list of 1s and 0s. 1 if corresponding face index is in a region, # 0 otherwise. all_regions_set = set(all_regions) material_list = [1 if f in all_regions_set else 0 for f in face_list] # Faces that belong to a region are colored red mesh.polygons.foreach_set("material_index", material_list) if add_to_model_objects: preserve_selection_use_operator(bpy.ops.mcell.model_objects_add, obj) mesh.validate(verbose=True) mesh.update()
def sbml2blender(inputFilePath,addObjects): print("loading .xml file... " + inputFilePath) #extrapolate object data from SBML file csgObjects = readSBMLFileCSGObject(inputFilePath) paramObject = readSBMLFileParametricObject(inputFilePath) print("length of objects: " + str(len(csgObjects))) #generates sphere or bounding box in Blender #track average endosome size sum_size = 0.0 #sum of volumes n_size = 0.0 #number of endosomes #track average endosome surface area sum_surf = 0.0 n_surf = 0.0 csgObjectNames = [] domainTypes = [] name = [] size = [] location = [] rotation = [] domain = [] ind = 0 for csgobject in csgObjects: if( csgobject[1] == 'SOLID_SPHERE' or csgobject[1] == 'sphere'): name.append(csgobject[0]) size.append([float(csgobject[2]), float(csgobject[3]), float(csgobject[4])]) location.append([float(csgobject[8]), float(csgobject[9]), float(csgobject[10])]) rotation.append([float(csgobject[5]), float(csgobject[6]), float(csgobject[7])]) domain.append(csgobject[11]) if domain[ind] not in domainTypes: domainTypes.append(domain[ind]) csgObjectNames.append(domain[ind]) sum_size += (4.0/3.0)*(3.14)*(size[ind][0])*(size[ind][1])*(size[ind][2]) n_size += 1 sum_surf += surface_area_sphere(size[ind][0],size[ind][1],size[ind][2]) n_surf += 1 ind = ind + 1 for domainType in domainTypes: ind = 0 print(domainType) for csgObjectName in csgObjectNames: print(csgObjectName) if domain[ind]==domainType: print("match") obj = generateSphere(domainType+str(ind),size[ind],location[ind],rotation[ind]) ind = ind + 1 bpy.ops.object.select_pattern(pattern=domainType+'*') bpy.ops.object.join() obj.name = domainType bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.faces_shade_smooth() bpy.ops.object.mode_set(mode='OBJECT') if addObjects: preserve_selection_use_operator(bpy.ops.mcell.model_objects_add, obj) bpy.ops.object.select_all(action='DESELECT') namingPatterns = domainTypes print(namingPatterns) ''' #bpy.ops.object.join() print("Here are the domains: ") print(csgObjectNames) #extract groups of strings with a lvenshtein distance less than 4 csgObjectNames.sort() namingPatterns = [] # while len(csgObjectNames) > 0: for domainType in domainTypes: print(domainType) #namingPatterns.append([x for x in csgObjectNames if domainType==x]) #csgObjectNames = [x for x in csgObjectNames if domainType==x] #extract common prefix for groups of strings namingPatterns = domainTypes print(namingPatterns) #namingPatterns = [common_prefix(x) for x in namingPatterns] #group objects by pattern - now domainType print(namingPatterns) for namingPattern in namingPatterns: #for domainType in domainTypes: print("Current domain: ") print(namingPattern) bpy.ops.object.select_name(name=format(namingPattern), extend=False) #bpy.ops.object.select_pattern(pattern='{0}*'.format(namingPattern), extend=False) #bpy.ops.object.select_pattern(pattern="devin2", extend=False) #bpy.ops.object.select_pattern(pattern="ivan1", extend=False) bpy.ops.object.join() obj = bpy.data.objects[bpy.context.active_object.name] #obj.name = namingPattern obj.name = namingPattern bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.faces_shade_smooth() bpy.ops.object.mode_set(mode='OBJECT') if addObjects: preserve_selection_use_operator(bpy.ops.mcell.model_objects_add, obj) #for name in csgObjectNames: #bpy.ops.object.select_by_type(type='MESH', extend=False) #bpy.ops.object.join() ''' csgObjectNames = [] for csgobject in csgObjects: if( csgobject[1] == 'SOLID_CUBE' or csgobject[1] == 'cube'): name = csgobject[0] location = [float(csgobject[2]), float(csgobject[3]), float(csgobject[4])] size = [float(csgobject[2]), float(csgobject[3]), float(csgobject[4])] location = [float(csgobject[8]), float(csgobject[9]), float(csgobject[10])] obj = generateCube(name,size,location) csgObjectNames.append(name) # if addObjects: # preserve_selection_use_operator(bpy.ops.mcell.model_objects_add, obj) #extract groups of strings with a lvenshtein distance less than 4 csgObjectNames.sort() namingPatterns = [] while len(csgObjectNames) > 0: namingPatterns.append([x for x in csgObjectNames if levenshtein(csgObjectNames[0],x) <= 4]) csgObjectNames = [x for x in csgObjectNames if levenshtein(csgObjectNames[0],x) > 4] #extract common prefix for groups of strings namingPatterns = [common_prefix(x) for x in namingPatterns] #group objects by pattern for namingPattern in namingPatterns: bpy.ops.object.select_pattern(pattern='{0}*'.format(namingPattern), extend=False) bpy.ops.object.join() obj = bpy.data.objects[bpy.context.active_object.name] obj.name = namingPattern if addObjects: preserve_selection_use_operator(bpy.ops.mcell.model_objects_add, obj) # print("The average endosome size is: " + str((sum_size/(n_size*1.0)))) # print("The average endosome surface area is " + str((sum_surf/(n_surf*1.0)))) for csgobject in paramObject: obj = generateMesh(csgobject) if addObjects: preserve_selection_use_operator(bpy.ops.mcell.model_objects_add, obj)