"Could not convert string to float" when importing CSV to Blender - python

I have a script I'm trying to use (not mine) which is meant to import CSV data into Blender as a mesh.
I have two CSV files which are two parts of the same model, the script works fine for importing one of the CSV files but throws a "ValueError" when I try to import the second.
The error can be seen here:
As far as I know there's only one "-1" in the script, I've tried changing it, removing it, nothing works, I still get the same error.
I've also tried changing the encoding on the CVS files themselves but that didn't work either.
I don't know much about scripting and I'm at my wits end, any help would be greatly appreciated.
The script I'm using is here:
https://github.com/sbobovyc/GameTools/blob/master/Blender/import_pix.py
# ##### 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 #####
# <pep8 compliant>
import bpy
import csv
import mathutils
from bpy_extras.io_utils import unpack_list, unpack_face_list, axis_conversion
from bpy.props import (BoolProperty,
FloatProperty,
StringProperty,
EnumProperty,
)
from collections import OrderedDict
bl_info = {
"name": "PIX CSV",
"author": "Stanislav Bobovych",
"version": (1, 0, 0),
"blender": (2, 7, 8),
"location": "File > Import-Export",
"description": "Import PIX csv dump of mesh. Import mesh, normals and UVs.",
"category": "Import"}
class PIX_CSV_Operator(bpy.types.Operator):
bl_idname = "object.pix_csv_importer"
bl_label = "Import PIX csv"
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
filter_glob = StringProperty(default="*.csv", options={'HIDDEN'})
mirror_x = bpy.props.BoolProperty(name="Mirror X",
description="Mirror all the vertices across X axis",
default=True)
vertex_order = bpy.props.BoolProperty(name="Change vertex order",
description="Reorder vertices in counter-clockwise order",
default=True)
axis_forward = EnumProperty(
name="Forward",
items=(('X', "X Forward", ""),
('Y', "Y Forward", ""),
('Z', "Z Forward", ""),
('-X', "-X Forward", ""),
('-Y', "-Y Forward", ""),
('-Z', "-Z Forward", ""),
),
default='Z')
axis_up = EnumProperty(
name="Up",
items=(('X', "X Up", ""),
('Y', "Y Up", ""),
('Z', "Z Up", ""),
('-X', "-X Up", ""),
('-Y', "-Y Up", ""),
('-Z', "-Z Up", ""),
),
default='Y',
)
def execute(self, context):
keywords = self.as_keywords(ignore=("axis_forward",
"axis_up",
"filter_glob"))
global_matrix = axis_conversion(from_forward=self.axis_forward,
from_up=self.axis_up,
).to_4x4()
keywords["global_matrix"] = global_matrix
print(keywords)
importCSV(**keywords)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
def draw(self, context):
layout = self.layout
col = layout.column()
col.label(text="Import options")
row = col.row()
row.prop(self, "mirror_x")
row = col.row()
row.prop(self, "vertex_order")
layout.prop(self, "axis_forward")
layout.prop(self, "axis_up")
def make_mesh(verteces, faces, normals, uvs, global_matrix):
mesh = bpy.data.meshes.new('name')
mesh.vertices.add(len(verteces))
mesh.vertices.foreach_set("co", unpack_list(verteces))
mesh.tessfaces.add(len(faces))
mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
index = 0
for vertex in mesh.vertices:
vertex.normal = normals[index]
index += 1
uvtex = mesh.tessface_uv_textures.new()
uvtex.name = "UV"
for face, uv in enumerate(uvs):
data = uvtex.data[face]
data.uv1 = uv[0]
data.uv2 = uv[1]
data.uv3 = uv[2]
mesh.update(calc_tessface=False, calc_edges=False)
obj = bpy.data.objects.new('name', mesh)
# apply transformation matrix
obj.matrix_world = global_matrix
bpy.context.scene.objects.link(obj) # link object to scene
def importCSV(filepath=None, mirror_x=False, vertex_order=True, global_matrix=None):
if global_matrix is None:
global_matrix = mathutils.Matrix()
if filepath == None:
return
vertex_dict = {}
normal_dict = {}
vertices = []
faces = []
normals = []
uvs = []
with open(filepath) as f:
reader = csv.reader(f)
next(reader) # skip header
# face_count = sum(1 for row in reader) / 3
# print(face_count)
f.seek(0)
reader = csv.reader(f)
next(reader) # skip header
current_face = []
current_uv = []
i = 0
x_mod = 1
if mirror_x:
x_mod = -1
for row in reader:
vertex_index = int(row[0])
vertex_dict[vertex_index] = (x_mod*float(row[2]), float(row[3]), float(row[4]))
#TODO how are axis really ligned up?
# x, y, z = (vertex_dict[vertex_index][0], vertex_dict[vertex_index][1], vertex_dict[vertex_index][2])
# vertex_dict[vertex_index] = (x, z, y)
normal_dict[vertex_index] = (float(row[6]), float(row[7]), float(row[8]))
#TODO add support for changing the origin of UV coords
uv = (float(row[9]), 1.0 - float(row[10])) # modify V
if i < 2:
current_face.append(vertex_index)
current_uv.append(uv)
i += 1
else:
current_face.append(vertex_index)
#TODO add option to change order of marching vertices
if vertex_order:
faces.append((current_face[2], current_face[1], current_face[0]))
else:
faces.append(current_face)
current_uv.append(uv)
uvs.append(current_uv)
current_face = []
current_uv = []
i = 0
for i in range(len(vertex_dict)):
if i in vertex_dict:
pass
else:
# print("missing",i)
vertex_dict[i] = (0, 0, 0)
normal_dict[i] = (0, 0, 0)
# dictionary sorted by key
vertex_dict = OrderedDict(sorted(vertex_dict.items(), key=lambda t: t[0]))
normal_dict = OrderedDict(sorted(normal_dict.items(), key=lambda t: t[0]))
for key in vertex_dict:
vertices.append(list(vertex_dict[key]))
# print(key,vertex_dict[key])
for key in normal_dict:
normals.append(list(normal_dict[key]))
# print(vertices)
# print(faces)
# print(normals)
# print(uvs)
make_mesh(vertices, faces, normals, uvs, global_matrix)
def menu_func_import(self, context):
self.layout.operator(PIX_CSV_Operator.bl_idname, text="PIX CSV (.csv)")
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_import.append(menu_func_import)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_import.remove(menu_func_import)
if __name__ == "__main__":
# register()
# These run the script from "Run script" button
bpy.utils.register_class(PIX_CSV_Operator)
bpy.ops.object.pix_csv_importer('INVOKE_DEFAULT')

Can you search if the string -, occurs anywhere in the CSV file that doesn’t work? - mkrieger1

Related

Make an editable table in PySimpleGUI?

Hello I am using a Table element from PySimpleGUI. I would like for the user to be able to edit the data inside it.
I have seen some mentions of it. Is it possible? This guy was using PySimpleGUIQt, while I am using the PySimpleGUI on top of tkinter.
It's much difficult for me to build it by pure PySimpleGUI code.
If go it with new class inherited from sg.Table, some variables as argument or global variables not required.
Here, colors of cell not considered in Entry.
All tkinter code in function edit_cell of following example.
import PySimpleGUI as sg
import random, string
# ------ Some functions to help generate data for the table ------
def word():
return ''.join(random.choice(string.ascii_lowercase) for i in range(10))
def number(max_val=1000):
return random.randint(0, max_val)
def make_table(num_rows, num_cols):
data = [[j for j in range(num_cols)] for i in range(num_rows)]
data[0] = [word() for _ in range(num_cols)]
for i in range(0, num_rows):
data[i] = [i, word(), *[number() for i in range(num_cols - 1)]]
return data
def edit_cell(window, key, row, col, justify='left'):
global textvariable, edit
def callback(event, row, col, text, key):
global edit
widget = event.widget
if key == 'Return':
text = widget.get()
print(text)
widget.destroy()
widget.master.destroy()
values = list(table.item(row, 'values'))
values[col] = text
table.item(row, values=values)
edit = False
if edit or row <= 0:
return
edit = True
root = window.TKroot
table = window[key].Widget
text = table.item(row, "values")[col]
x, y, width, height = table.bbox(row, col)
frame = sg.tk.Frame(root)
frame.place(x=x, y=y, anchor="nw", width=width, height=height)
textvariable = sg.tk.StringVar()
textvariable.set(text)
entry = sg.tk.Entry(frame, textvariable=textvariable, justify=justify)
entry.pack()
entry.select_range(0, sg.tk.END)
entry.icursor(sg.tk.END)
entry.focus_force()
entry.bind("<Return>", lambda e, r=row, c=col, t=text, k='Return':callback(e, r, c, t, k))
entry.bind("<Escape>", lambda e, r=row, c=col, t=text, k='Escape':callback(e, r, c, t, k))
def main_example1():
global edit
edit = False
# ------ Make the Table Data ------
# sg.Print('Creating table...')
data = make_table(num_rows=1_000, num_cols=6)
# headings = [str(data[0][x])+' ..' for x in range(len(data[0]))]
headings = [f'Col {col}' for col in range(len(data[0]))]
# sg.Print('Done creating table. Creating GUI...')
sg.set_options(dpi_awareness=True)
layout = [[sg.Table(values=data, headings=headings, max_col_width=25,
auto_size_columns=True,
# display_row_numbers=True,
justification='right',
num_rows=20,
alternating_row_color=sg.theme_button_color()[1],
key='-TABLE-',
# selected_row_colors='red on yellow',
# enable_events=True,
# select_mode=sg.TABLE_SELECT_MODE_BROWSE,
expand_x=True,
expand_y=True,
enable_click_events=True, # Comment out to not enable header and other clicks
)],
[sg.Button('Read'), sg.Button('Double'), sg.Button('Change Colors')],
[sg.Text('Cell clicked:'), sg.T(k='-CLICKED-')]]
window = sg.Window('Table Element - Example 1', layout, resizable=True, finalize=True)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
elif isinstance(event, tuple):
cell = row, col = event[2]
window['-CLICKED-'].update(cell)
edit_cell(window, '-TABLE-', row+1, col, justify='right')
window.close()
main_example1()
I would strongly suggest use MutiLine for showing table, which is much simpler to manage and can be easily updated etc. The Same table effects can be achieved by less lines of code. Giving a sample code here from my own database program with uses Sqlite3 table.
def ViewTable (TableNme):
try: # LOAD TABLE FROM Sqlite3 Database
txt2="SELECT * FROM {} ".format(TableNme)
cursor.execute(txt2)
##Include headers###
txt2='S.No '
for j in fields: txt2=txt2+j +" "
txt2=txt2+'\n'
#converts the table into string separated by Comma
#fine as long as table is not very massive running more than 3 Mbs, having more than 1000 records
while True:
h1=cursor.fetchone()
if not h1: break
for j in h1:txt2=txt2+str(j)+" "
txt2=txt2+'\n'
#sg.popup('Archieved table', txt2)
#Define text to load by text= before calling me
layout2 = [[sg.Multiline(txt2,size=(28,28),key='-Items-'),],[sg.Ok()] ]
sg.Window('Scroll to see the whole database', layout2,finalize=True).read(close=True)
except:
sg.popup_error('Failed','Access denied or Memory full.')

Python Chess Data (FEN) into Stockfish for Python

I am trying to use stockfish to evaluate a chess position using FEN notation all in Python. I am mainly using two libraries (pgnToFen I found on github here: https://github.com/SindreSvendby/pgnToFen and Stockfish the MIT licensed one here: https://github.com/zhelyabuzhsky/stockfish). After many bugs I have reached problem after problem. Stockfish not only can't analyse this FEN position (3b2k1/1p3pp1/8/3pP1P1/pP3P2/P2pB3/6K1/8 b f3 -) but it infinitely loops! "No worries!" and thought changing the source code would be accomplishable. Changed to _put(), but basically I am unable to put dummy values in because stdin.flush() won't execute once I give it those values! Meaning I don't even think I can skip to the next row in my dataframe. :( The code I changed is below.
def _put(self, command: str, tmp_time) -> None:
if not self.stockfish.stdin:
raise BrokenPipeError()
self.stockfish.stdin.write(f"{command}\n")
try:
self.stockfish.stdin.flush()
except:
if command != "quit":
self.stockfish.stdin.write('isready\n')
try:
time.sleep(tmp_time)
self.stockfish.stdin.flush()
except:
#print ('Imma head out', file=sys.stderr)
raise ValueError('Imma head out...')
#sys.stderr.close()
def get_evaluation(self) -> dict:
"""Evaluates current position
Returns:
A dictionary of the current advantage with "type" as "cp" (centipawns) or "mate" (checkmate in)
"""
evaluation = dict()
fen_position = self.get_fen_position()
if "w" in fen_position: # w can only be in FEN if it is whites move
compare = 1
else: # stockfish shows advantage relative to current player, convention is to do white positive
compare = -1
self._put(f"position {fen_position}", 5)
self._go()
x=0
while True:
x=x+1
text = self._read_line()
#print(text)
splitted_text = text.split(" ")
if splitted_text[0] == "info":
for n in range(len(splitted_text)):
if splitted_text[n] == "score":
evaluation = {
"type": splitted_text[n + 1],
"value": int(splitted_text[n + 2]) * compare,
}
elif splitted_text[0] == "bestmove":
return evaluation
elif x == 500:
evaluation = {
"type": 'cp',
"value": 10000,
}
return evaluation
and last but not least change to the init_ contructor below:
self._stockfish_major_version: float = float(self._read_line().split(" ")[1])
And the code where I am importing this code to is below, this is where errors pop up.
import pandas as pd
import re
import nltk
import numpy as np
from stockfish import Stockfish
import os
import sys
sys.path.insert(0, r'C:\Users\path\to\pgntofen')
import pgntofen
#nltk.download('punkt')
#Changed models.py for major version line 39 in stockfish from int to float
stockfish = Stockfish(r"C:\Users\path\to\Stockfish.exe")
file = r'C:\Users\path\to\selenium-pandas output.csv'
chunksize = 10 ** 6
for chunk in pd.read_csv(file, chunksize=chunksize):
for index, row in chunk.iterrows():
FullMovesStr = str(row['FullMoves'])
FullMovesStr = FullMovesStr.replace('+', '')
if "e.p" in FullMovesStr:
row.to_csv(r'C:\Users\MyName\Logger.csv', header=None, index=False, mode='a')
print('Enpassant')
continue
tokens = nltk.word_tokenize(FullMovesStr)
movelist = []
for tokenit in range(len(tokens)):
if "." in str(tokens[tokenit]):
try:
tokenstripped = re.sub(r"[0-9]+\.", "", tokens[tokenit])
token = [tokenstripped, tokens[tokenit+1]]
movelist.append(token)
except:
continue
else:
continue
DFMoves = pd.DataFrame(movelist, columns=[['WhiteMove', 'BlackMove']])
DFMoves['index'] = row['index']
DFMoves['Date'] = row['Date']
DFMoves['White'] = row['White']
DFMoves['Black'] = row['Black']
DFMoves['W ELO'] = row['W ELO']
DFMoves['B ELO'] = row['B ELO']
DFMoves['Av ELO'] = row['Av ELO']
DFMoves['Event'] = row['Event']
DFMoves['Site'] = row['Site']
DFMoves['ECO'] = row['ECO']
DFMoves['Opening'] = row['Opening']
pd.set_option('display.max_rows', DFMoves.shape[0]+1)
print(DFMoves[['WhiteMove', 'BlackMove']])
seqmoves = []
#seqmovesBlack = []
evalmove = []
pgnConverter = pgntofen.PgnToFen()
#stockfish.set_fen_position("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
#rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
for index, row in DFMoves.iterrows():
try:
stockfish.set_fen_position("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
except:
evalmove.append("?")
continue
#stockfish.set_fen_position("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
pgnConverter.resetBoard()
WhiteMove = str(row['WhiteMove'])
BlackMove = str(row['BlackMove'])
if index == 0:
PGNMoves1 = [WhiteMove]
seqmoves.append(WhiteMove)
#seqmoves.append(BlackMove)
else:
seqmoves.append(WhiteMove)
#seqmoves.append(BlackMove)
PGNMoves1 = seqmoves.copy()
#print(seqmoves)
try:
pgnConverter.pgnToFen(PGNMoves1)
fen = pgnConverter.getFullFen()
except:
break
try:
stockfish.set_fen_position(fen)
print(stockfish.get_board_visual())
evalpos = stockfish.get_evaluation()
evalmove.append(evalpos)
except:
pass
try:
stockfish.set_fen_position("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
except:
evalmove.append("?")
continue
pgnConverter.resetBoard()
if index == 0:
PGNMoves2 = [WhiteMove, BlackMove]
seqmoves.append(BlackMove)
else:
seqmoves.append(BlackMove)
PGNMoves2 = seqmoves.copy()
try:
pgnConverter.pgnToFen(PGNMoves2)
fen = pgnConverter.getFullFen()
except:
break
try:
stockfish.set_fen_position(fen)
print(stockfish.get_board_visual())
evalpos = stockfish.get_evaluation()
print(evalpos)
evalmove.append(evalpos)
except:
pass
#DFMoves['EvalWhite'] = evalwhite
#DFMoves['EvalBlack'] = evalblack
print(evalmove)
So the detailed question is getting stockfish.get_evalution() to just skip, or better yet fix the problem, for this ( 3b2k1/1p3pp1/8/3pP1P1/pP3P2/P2pB3/6K1/8 b f3 - ) FEN position. I have been working on this problem for quite a while so any insight into this would be very much appreciated.
My specs are Windows 10, Python 3.9, Processor:Intel(R) Core(TM) i9-10980XE CPU # 3.00GHz 3.00 GHz and RAM is 64.0 GB.
Thanks :)
Ok. It seems your fen is invalid (3b2k1/1p3pp1/8/3pP1P1/pP3P2/P2pB3/6K1/8 b f3 -). So check that. And python-chess (https://python-chess.readthedocs.io/en/latest/index.html) library allows you to use FEN AND chess engines. So, pretty cool no ? Here is an example of theses two fantastics tools :
import chess
import chess.engine
import chess.pgn
pgn = open("your_pgn_file.pgn")
game = chess.pgn.read_game(pgn)
engine = chess.engine.SimpleEngine.popen_uci("your_stockfish_path.exe")
# Iterate through all moves, play them on a board and analyse them.
board = game.board()
for move in game.mainline_moves():
board.push(move)
print(engine.analyse(board, chess.engine.Limit(time=0.1))["score"])

(Python) Change pagesize and format of PDF file generated with xtopdf

I want to convert an xlsx with Python. I used the modules tablib and xtopdf to build a well structured table. Works excellent! Unfortunately the content does not fit on one pdf page. So I wanted to change the pagesize and format to horizontal A3. But I don't know how that could work. My code:
import random
import tablib
from openpyxl import load_workbook
from xtopdf import PDFWriter
from pyPdf import PdfFileWriter, PdfFileReader
workbook = load_workbook('C:/Users/user1/Testexcel.xlsx', guess_types=True, data_only=True)
worksheet = workbook.get_sheet_by_name('Testsheet')
ws_range = worksheet.iter_rows('A4:H6')
# Helper function to output a string to both screen and PDF.
def print_and_write(pw, strng):
print strng
pw.writeLine(strng)
# Create an empty Dataset and set its headers.
data = tablib.Dataset()
data.headers = ['col1', 'col2', 'col3', 'col4']
widths = [30, 20, 10, 20] # Display widths for columns.
for row in ws_range:
col1 = str(row[0].value)
col2 = str(row[1].value)
col3 = str(row[2].value)
col4 = str(row[3].value)
columns = [col1, col2, col3, col4]
row = [ str(col).center(widths[idx]) for idx, col in enumerate(columns) ]
data.append(row)
# Set up the PDFWriter.
pw = PDFWriter('C:/Users/user1/Test.pdf')
pw.setFont('Courier', 10)
pw.setHeader('Test')
pw.setFooter('Test')
# Generate header and data rows as strings; output them to screen and PDF.
separator = '-' * sum(widths)
print_and_write(pw, separator)
# Output headers
header_strs = [ header.center(widths[idx]) for idx, header in enumerate(data.headers) ]
print_and_write(pw, ''.join(header_strs))
print_and_write(pw, separator)
# Output data
for row in data:
print_and_write(pw, ''.join(row))
print_and_write(pw, separator)
pw.close()
Found out that the PDFWriter from xtopdf itself instanciates an canvas object of the reportlab library. In the canvas class an attribute pagesize is declared which is setted by default to 'A4'. But if I change the entry to 'A3' the result pdf still is in 'A4'.
class Canvas(textobject._PDFColorSetter):
from reportlab.pdfgen import canvas
c = canvas.Canvas("hello.pdf")
from reportlab.lib.units import inch
# move the origin up and to the left
c.translate(inch,inch)
# define a large font
c.setFont("Helvetica", 80)
# choose some colors
c.setStrokeColorRGB(0.2,0.5,0.3)
c.setFillColorRGB(1,0,1)
# draw a rectangle
c.rect(inch,inch,6*inch,9*inch, fill=1)
# make text go straight up
c.rotate(90)
# change color
c.setFillColorRGB(0,0,0.77)
# say hello (note after rotate the y coord needs to be negative!)
c.drawString(3*inch, -3*inch, "Hello World")
c.showPage()
c.save()
"""
def __init__(self,filename,
pagesize='A3',
bottomup = 1,
pageCompression=None,
encoding = None,
invariant = None,
verbosity=0):
"""Create a canvas of a given size. etc.
You may pass a file-like object to filename as an alternative to
a string.
Most of the attributes are private - we will use set/get methods
as the preferred interface. Default page size is A4."""
if pagesize is None: pagesize = 'A3'
if encoding is None: encoding = rl_config.defaultEncoding
if invariant is None: invariant = rl_config.invariant
self._filename = filename
self._encodingName = encoding
self._doc = pdfdoc.PDFDocument(encoding,
compression=pageCompression,
invariant=invariant, filename=filename)
#this only controls whether it prints 'saved ...' - 0 disables
self._verbosity = verbosity
#this is called each time a page is output if non-null
self._onPage = None
self._pagesize = pagesize
self._pageRotation = 0
#self._currentPageHasImages = 0
self._pageTransition = None
self._pageDuration = None
self._destinations = {} # dictionary of destinations for cross indexing.
self.setPageCompression(pageCompression)
self._pageNumber = 1 # keep a count
#self3 = [] #where the current page's marking operators accumulate
# when we create a form we need to save operations not in the form
self._codeStack = []
self._restartAccumulators() # restart all accumulation state (generalized, arw)
self._annotationCount = 0
self._outlines = [] # list for a name tree
self._psCommandsBeforePage = [] #for postscript tray/font commands
self._psCommandsAfterPage = [] #for postscript tray/font commands
#PostScript has the origin at bottom left. It is easy to achieve a top-
#down coord system by translating to the top of the page and setting y
#scale to -1, but then text is inverted. So self.bottomup is used
#to also set the text matrix accordingly. You can now choose your
#drawing coordinates.
self.bottomup = bottomup
self.imageCaching = rl_config.defaultImageCaching
self._make_preamble()
self.init_graphics_state()
self.state_stack = []
edit: I think the changes in the reportlab module are not accepted by the system. Tried to remove the dictionary reportlab and tried to import it then in the commandline. Ironically it works ylthough python should not find that module anymore.
try this
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
c = canvas.Canvas("hello.pdf", pagesize = (297 * mm, 420 * mm))
# or (420 * mm, 297 * mm) if you want it in portrait format
# values for inch: 11.69 * inch , 16.53 * inch
#the following would create an empty page
c.showPage()
c.save()
Just forked a project named xtopdf at bitbucket and made the following change:
##------------------------ PDFWriter.__init__ ----------------------------
- def __init__(self, pdf_fn):
+ def __init__(self, pdf_fn, pagesize='A4'):
'''
Constructor.
"pdf_fn" arg is the name of the PDF file to be created.
'''
self.__pdf_fn = pdf_fn # file name of PDF file
- self.__canv = canvas.Canvas(pdf_fn) # canvas to write on
+ self.__canv = canvas.Canvas(pdf_fn, pagesize) # canvas to write on
self.__font_name = None # font name
self.__font_size = None # font size
self.__header_str = None # header string (partial)
Can you try it? use pw = PDFWriter('C:/Users/user1/Test.pdf', 'A3').

How to export a mesh's movement from Blender?

I have a simple UV Sphere in Blender which moves from point A to point B (I've set it up by pressing "I" button on location A, clicked on LocRot then clicked on LocRot on point B as well).
I'd like to export its movement.
For exporting a camera's movement I use
Blender Foundation\Blender\2.74\scripts\addons\io_anim_camera.py
(This is Cameras & Markers (.py) exporter.)
It's produces following output:
...
...
# new frame
scene.frame_set(1 + frame)
obj = cameras['Camera.003']
obj.location = -272.1265563964844, -155.54611206054688, -121.49121856689453 <-- here is the current coordinate of the camera, this is what I need for spheres
obj.scale = 0.9999998807907104, 0.9999998807907104, 0.9999999403953552
obj.rotation_euler = -1.6492990255355835, 0.00035389664117246866, 0.009288366883993149
obj.keyframe_insert('location')
obj.keyframe_insert('scale')
obj.keyframe_insert('rotation_euler')
data = obj.data
data.lens = 35.0
data.keyframe_insert('lens')
...
...
I'm looking for the same thing for meshes.
So here is the code of the basic exporter for cameras:
# ##### 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 #####
# <pep8 compliant>
bl_info = {
"name": "Export Camera Animation",
"author": "Campbell Barton",
"version": (0, 1),
"blender": (2, 57, 0),
"location": "File > Export > Cameras & Markers (.py)",
"description": "Export Cameras & Markers (.py)",
"warning": "",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
"Scripts/Import-Export/Camera_Animation",
"support": 'OFFICIAL',
"category": "Import-Export",
}
import bpy
def write_cameras(context, filepath, frame_start, frame_end, only_selected=False):
data_attrs = (
'lens',
'shift_x',
'shift_y',
'dof_distance',
'clip_start',
'clip_end',
'draw_size',
)
obj_attrs = (
'hide_render',
)
fw = open(filepath, 'w').write
scene = bpy.context.scene
cameras = []
for obj in scene.objects:
if only_selected and not obj.select:
continue
if obj.type != 'CAMERA':
continue
cameras.append((obj, obj.data))
frame_range = range(frame_start, frame_end + 1)
fw("import bpy\n"
"cameras = {}\n"
"scene = bpy.context.scene\n"
"frame = scene.frame_current - 1\n"
"\n")
for obj, obj_data in cameras:
fw("data = bpy.data.cameras.new(%r)\n" % obj.name)
for attr in data_attrs:
fw("data.%s = %s\n" % (attr, repr(getattr(obj_data, attr))))
fw("obj = bpy.data.objects.new(%r, data)\n" % obj.name)
for attr in obj_attrs:
fw("obj.%s = %s\n" % (attr, repr(getattr(obj, attr))))
fw("scene.objects.link(obj)\n")
fw("cameras[%r] = obj\n" % obj.name)
fw("\n")
for f in frame_range:
scene.frame_set(f)
fw("# new frame\n")
fw("scene.frame_set(%d + frame)\n" % f)
for obj, obj_data in cameras:
fw("obj = cameras['%s']\n" % obj.name)
matrix = obj.matrix_world.copy()
fw("obj.location = %r, %r, %r\n" % matrix.to_translation()[:])
fw("obj.scale = %r, %r, %r\n" % matrix.to_scale()[:])
fw("obj.rotation_euler = %r, %r, %r\n" % matrix.to_euler()[:])
fw("obj.keyframe_insert('location')\n")
fw("obj.keyframe_insert('scale')\n")
fw("obj.keyframe_insert('rotation_euler')\n")
# only key the angle
fw("data = obj.data\n")
fw("data.lens = %s\n" % obj_data.lens)
fw("data.keyframe_insert('lens')\n")
fw("\n")
# now markers
fw("# markers\n")
for marker in scene.timeline_markers:
fw("marker = scene.timeline_markers.new(%r)\n" % marker.name)
fw("marker.frame = %d + frame\n" % marker.frame)
# will fail if the cameras not selected
if marker.camera:
fw("marker.camera = cameras.get(%r)\n" % marker.camera.name)
fw("\n")
from bpy.props import StringProperty, IntProperty, BoolProperty
from bpy_extras.io_utils import ExportHelper
class CameraExporter(bpy.types.Operator, ExportHelper):
"""Save a python script which re-creates cameras and markers elsewhere"""
bl_idname = "export_animation.cameras"
bl_label = "Export Camera & Markers"
filename_ext = ".py"
filter_glob = StringProperty(default="*.py", options={'HIDDEN'})
frame_start = IntProperty(name="Start Frame",
description="Start frame for export",
default=1, min=1, max=300000)
frame_end = IntProperty(name="End Frame",
description="End frame for export",
default=250, min=1, max=300000)
only_selected = BoolProperty(name="Only Selected",
default=True)
def execute(self, context):
write_cameras(context, self.filepath, self.frame_start, self.frame_end, self.only_selected)
return {'FINISHED'}
def invoke(self, context, event):
self.frame_start = context.scene.frame_start
self.frame_end = context.scene.frame_end
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}
def menu_export(self, context):
import os
default_path = os.path.splitext(bpy.data.filepath)[0] + ".py"
self.layout.operator(CameraExporter.bl_idname, text="Cameras & Markers (.py)").filepath = default_path
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_export.append(menu_export)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_export.remove(menu_export)
if __name__ == "__main__":
register()
So is it possible? How to change this code to export the movement of a spheres?
Well, If you want to export the movement not as a Python script but in Text or in CSV format. Then look at the following code snippet.
CSV export can work for camera like this:
fw("# frame camera x y z qx qy qz qw\n")
for f in frame_range:
scene.frame_set(f)
for obj, obj_data in cameras:
matrix = obj.matrix_world.copy()
fw("%d," % f)
fw("%s," % obj.name)
fw("%r,%r,%r," % matrix.to_translation()[:])
fw("%r,%r,%r,%r" % matrix.to_quaternion()[:])
fw("\n")
from bpy.props import StringProperty, IntProperty, BoolProperty
from bpy_extras.io_utils import ExportHelper
class CameraExporter(bpy.types.Operator, ExportHelper):
"""Export camera trajectory to a file"""
bl_idname = "export_trajectory.cameras"
bl_label = "Export camera trajectory"
filename_ext = ".csv"
filter_glob = StringProperty(default="*.csv", options={'HIDDEN'})
In my opinion it should work similarly for any other objects in scene.
Not yet tried for other objects though!

How to make PyCollada output multiple meshes to the same scene?

So I am using pyCollada to try to export multiple meshes to the same scene. Alas, whenever I try to do so, I can only see one of the meshes I have loaded in. Am I doing something wrong when I create the file? Each individual mesh renders perfectly if I separate them into their own file, but they fail when I attempt to output them to the same file. I have looked through the API, but the documentation is very limited. Any help would be appreciated.
My code is listed shown below.
# -*- coding: utf-8 -*-
"""
Created on Fri Jun 12 14:43:05 2015
#author: skylion
"""
# -*- coding: utf-8 -*-
"""
Created on Thu Jun 11 11:01:48 2015
#author: danaukes
"""
import sys
import popupcad_deprecated
import popupcad_manufacturing_plugins
import popupcad
from popupcad.filetypes.design import Design
import PySide.QtGui as qg
#Draws Collada stuff
from collada import *
import numpy
geom_index = 0;
def exportBodyToMesh(output):
# csg = output.csg
generic = output.generic_laminate()
# layers = generic.layers()
layerdef = d.return_layer_definition()
layerdef.refreshzvalues()
# layers = layerdef.layers
mesh = Collada()
nodes = []
for layer in layerdef.layers:
shapes = generic.geoms[layer]#TODO Add it in for other shapes
zvalue = layerdef.zvalue[layer]
height = zvalue * 1/ popupcad.internal_argument_scaling
print zvalue
if (len(shapes) == 0) : #In case there are no shapes.
print "No shapes skipping"
continue
print shapes
for s in shapes:
geom = createMeshFromShape(s, height, mesh)
mesh.geometries.append(geom)
effect = material.Effect("effect" + str(geom_index), [], "phone", diffuse=(1,0,0), specular=(0,1,0))
mat = material.Material("material" + str(geom_index), "mymaterial", effect)
matnode = scene.MaterialNode("materialref" + str(geom_index), mat, inputs=[])
mesh.effects.append(effect)
mesh.materials.append(mat)
geomnode = scene.GeometryNode(geom, [matnode])
node = scene.Node("node" + str(geom_index), children=[geomnode])
nodes.append(node)
print nodes
myscene = scene.Scene("myscene", nodes)
mesh.scenes.append(myscene)
mesh.scene = myscene
# layer_num = layer_num + 1 #Add the layer thicknes instead of simply + 1
filename = str(output) + '.dae'
mesh.write(filename)
#TODO Add handling in case rigid body has already been selected.
print filename + " has been saved"
def createMeshFromShape(s,layer_num, mesh):
s.exteriorpoints()
a = s.triangles3()
vertices = []
global geom_index
for coord in a:
for dec in coord:
vertices.append(dec[0]) #x-axis
vertices.append(dec[1]) #y-axis
vertices.append(layer_num ) #z-axi
#This scales the verticies properly.
vert_floats = [x/popupcad.internal_argument_scaling for x in vertices]
vert_src = source.FloatSource("cubeverts-array" + str(geom_index), numpy.array(vert_floats), ('X', 'Y', 'Z'))
geom = geometry.Geometry(mesh, "geometry" + str(geom_index), "mycube", [vert_src])
input_list = source.InputList()
input_list.addInput(0, 'VERTEX', "#cubeverts-array" + str(geom_index))
indices = numpy.array(range(0,(len(vertices) / 3)));
triset = geom.createTriangleSet(indices, input_list, "materialref")
geom_index += 1
triset.generateNormals()
geom.primitives.append(triset)
return geom
#Start of actual script
print sys.argv
app = qg.QApplication('exporter.py')
d = Design.open()
print "Loading..."
d.reprocessoperations()
operation = d.operations[3] #Identify bodies
for output in operation.output:
exportBodyToMesh(output)
print "All objects printed"
#sys.exit(app.exec_())
Your code to add the geometry to the scene is outside your inner loop. You're only adding the last geometry to the scene, rather than all of them. You should be creating multiple GeometryNode and adding all of them to the Scene.

Categories