Blender scripting - Incorrect texture add - python

I wrote a python script that automatically add a texture to the DAE model.
Usage: blender --background --python Script.py
This script gives an incorrect display of the texture:
import bpy
from math import pi
from mathutils import Quaternion
myscale = 0.1;
daepath = "input.dae"
bpy.ops.wm.read_factory_settings(use_empty=True)
# Import Dae
bpy.ops.wm.collada_import(filepath=daepath)
# Rotate
bpy.ops.transform.rotate(value=-pi/2, constraint_axis=(False, True, True))
bpy.ops.transform.resize(value=(myscale, myscale, myscale))
# Change to orthographic view and switch to topview
bpy.context.screen.areas[2].type = 'VIEW_3D'
rv3d = bpy.context.screen.areas[2].spaces[0].region_3d
rv3d.view_rotation = Quaternion((1.0, 0.0, 0.0, 0.0))
rv3d.view_perspective = "ORTHO"
rv3d.view_distance += 1000.0
# Unwrap
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.mesh.select_all(action = 'SELECT')
for oWindow in bpy.context.window_manager.windows:
oScreen = oWindow.screen
for oArea in oScreen.areas:
if oArea.type == 'VIEW_3D':
for oRegion in oArea.regions:
if oRegion.type == 'WINDOW':
override = {'window': oWindow, 'screen': oScreen, 'area': oArea, 'region': oRegion, 'scene': bpy.context.scene, 'edit_object': bpy.context.edit_object, 'active_object': bpy.context.active_object, 'selected_objects': bpy.context.selected_objects}
bpy.ops.uv.project_from_view(override , camera_bounds=False, correct_aspect=True, scale_to_bounds=True)
bpy.ops.object.mode_set(mode = 'OBJECT')
# Add Texture
imgpath = "input.jpg"
img = bpy.data.images.load(filepath=imgpath)
mat = bpy.data.materials['m0DefaultMaterial']
mat.diffuse_intensity = 1.0
mat.specular_intensity = 0.0
tex = bpy.data.textures.new("SomeName", 'IMAGE')
tex.image = img
slot = mat.texture_slots.add()
slot.texture = tex
# Save Dae
bpy.ops.wm.collada_export(filepath="output.dae")
If I divide the script into 2 parts (1 part before section # Unwrap) and run their in Blender
open app
choose scripting mode
open .py files in run
I get right result.
I was looking for all the similar problems, but I could not find the reason for this script behavior.
Tell me, please, where is the error?

Related

Making a 3D model in VTK solid instead of hollow inside

I'm trying to create 3D model of the skull using VTK [example]:(https://kitware.github.io/vtk-examples/site/Python/VisualizationAlgorithms/HeadBone/)
#!/usr/bin/env python
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import (
VTK_VERSION_NUMBER,
vtkVersion
)
from vtkmodules.vtkCommonDataModel import vtkMergePoints
from vtkmodules.vtkFiltersCore import (
vtkFlyingEdges3D,
vtkMarchingCubes
)
from vtkmodules.vtkFiltersModeling import vtkOutlineFilter
from vtkmodules.vtkIOImage import vtkMetaImageReader
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer
)
def main():
# vtkFlyingEdges3D was introduced in VTK >= 8.2
use_flying_edges = vtk_version_ok(8, 2, 0)
file_name = get_program_parameters()
colors = vtkNamedColors()
# Create the RenderWindow, Renderer and Interactor.
ren = vtkRenderer()
ren_win = vtkRenderWindow()
ren_win.AddRenderer(ren)
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# Create the pipeline.
reader = vtkMetaImageReader()
reader.SetFileName(file_name)
reader.Update()
locator = vtkMergePoints()
locator.SetDivisions(64, 64, 92)
locator.SetNumberOfPointsPerBucket(2)
locator.AutomaticOff()
if use_flying_edges:
try:
using_marching_cubes = False
iso = vtkFlyingEdges3D()
except AttributeError:
using_marching_cubes = True
iso = vtkMarchingCubes()
else:
using_marching_cubes = True
iso = vtkMarchingCubes()
iso.SetInputConnection(reader.GetOutputPort())
iso.ComputeGradientsOn()
iso.ComputeScalarsOff()
iso.SetValue(0, 1150)
if using_marching_cubes:
iso.SetLocator(locator)
iso_mapper = vtkPolyDataMapper()
iso_mapper.SetInputConnection(iso.GetOutputPort())
iso_mapper.ScalarVisibilityOff()
iso_actor = vtkActor()
iso_actor.SetMapper(iso_mapper)
iso_actor.GetProperty().SetColor(colors.GetColor3d('Ivory'))
outline = vtkOutlineFilter()
outline.SetInputConnection(reader.GetOutputPort())
outline_mapper = vtkPolyDataMapper()
outline_mapper.SetInputConnection(outline.GetOutputPort())
outline_actor = vtkActor()
outline_actor.SetMapper(outline_mapper)
# Add the actors to the renderer, set the background and size.
#
ren.AddActor(outline_actor)
ren.AddActor(iso_actor)
ren.SetBackground(colors.GetColor3d('SlateGray'))
ren.GetActiveCamera().SetFocalPoint(0, 0, 0)
ren.GetActiveCamera().SetPosition(0, -1, 0)
ren.GetActiveCamera().SetViewUp(0, 0, -1)
ren.ResetCamera()
ren.GetActiveCamera().Dolly(1.5)
ren.ResetCameraClippingRange()
ren_win.SetSize(640, 480)
ren_win.SetWindowName('HeadBone')
ren_win.Render()
iren.Start()
def get_program_parameters():
import argparse
description = 'Marching cubes surface of human bone.'
epilogue = '''
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('filename', help='FullHead.mhd.')
args = parser.parse_args()
return args.filename
def vtk_version_ok(major, minor, build):
"""
Check the VTK version.
:param major: Major version.
:param minor: Minor version.
:param build: Build version.
:return: True if the requested VTK version is greater or equal to the actual VTK version.
"""
needed_version = 10000000000 * int(major) + 100000000 * int(minor) + int(build)
try:
vtk_version_number = VTK_VERSION_NUMBER
except AttributeError: # as error:
ver = vtkVersion()
vtk_version_number = 10000000000 * ver.GetVTKMajorVersion() + 100000000 * ver.GetVTKMinorVersion() \
+ ver.GetVTKBuildVersion()
if vtk_version_number >= needed_version:
return True
else:
return False
if __name__ == '__main__':
main()
It appears that model works just fine, but there is something that I want to know. The model of the skull works perfectly fine, but the model density is not solid (it hollow inside). It generates only the surface of the model.
I want to know how I can fill the gap in the surface to get the full solid model.
In this example, you are trying to extract the isosurface (hollow) from the data.
vtkFlyingEdges3D() and vtkMarchingCubes() algorithms will create contours based on the iso.SetValue(0, 1150) and extract the surface for you. If you want to keep it filled, remove the contouring functions, i'e, vtkFlyingEdges3D() and vtkMarchingCubes() from your script and use some image data mapper instead of vtkPolydataMapper, it will show the entire object.

python-neat example broken

I'm trying to run the following code from python neat which allows you to apply genetic algorithms to neural networks. It is a very interesting concept only I cannot get the example code to run.
"""
2-input XOR example -- this is most likely the simplest possible example.
"""
from __future__ import print_function
import os
import neat
import visualize
# 2-input XOR inputs and expected outputs.
xor_inputs = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]
xor_outputs = [ (0.0,), (1.0,), (1.0,), (0.0,)]
def eval_genomes(genomes, config):
for genome_id, genome in genomes:
genome.fitness = 4.0
net = neat.nn.FeedForwardNetwork.create(genome, config)
for xi, xo in zip(xor_inputs, xor_outputs):
output = net.activate(xi)
genome.fitness -= (output[0] - xo[0]) ** 2
def run(config_file):
# Load configuration.
config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
neat.DefaultSpeciesSet, neat.DefaultStagnation,
config_file)
# Create the population, which is the top-level object for a NEAT run.
p = neat.Population(config)
# Add a stdout reporter to show progress in the terminal.
p.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
p.add_reporter(stats)
p.add_reporter(neat.Checkpointer(5))
# Run for up to 300 generations.
winner = p.run(eval_genomes, 300)
# Display the winning genome.
print('\nBest genome:\n{!s}'.format(winner))
# Show output of the most fit genome against training data.
print('\nOutput:')
winner_net = neat.nn.FeedForwardNetwork.create(winner, config)
for xi, xo in zip(xor_inputs, xor_outputs):
output = winner_net.activate(xi)
print("input {!r}, expected output {!r}, got {!r}".format(xi, xo, output))
node_names = {-1:'A', -2: 'B', 0:'A XOR B'}
visualize.draw_net(config, winner, True, node_names=node_names)
visualize.plot_stats(stats, ylog=False, view=True)
visualize.plot_species(stats, view=True)
p = neat.Checkpointer.restore_checkpoint('neat-checkpoint-4')
p.run(eval_genomes, 10)
if __name__ == '__main__':
# Determine path to configuration file. This path manipulation is
# here so that the script will run successfully regardless of the
# current working directory.
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward')
run(config_path)
Here is the config file
#--- parameters for the XOR-2 experiment ---#
[NEAT]
fitness_criterion = max
fitness_threshold = 3.9
pop_size = 150
reset_on_extinction = False
[DefaultGenome]
# node activation options
activation_default = sigmoid
activation_mutate_rate = 0.0
activation_options = sigmoid
# node aggregation options
aggregation_default = sum
aggregation_mutate_rate = 0.0
aggregation_options = sum
# node bias options
bias_init_mean = 0.0
bias_init_stdev = 1.0
bias_max_value = 30.0
bias_min_value = -30.0
bias_mutate_power = 0.5
bias_mutate_rate = 0.7
bias_replace_rate = 0.1
# genome compatibility options
compatibility_disjoint_coefficient = 1.0
compatibility_weight_coefficient = 0.5
# connection add/remove rates
conn_add_prob = 0.5
conn_delete_prob = 0.5
# connection enable options
enabled_default = True
enabled_mutate_rate = 0.01
feed_forward = True
initial_connection = full
# node add/remove rates
node_add_prob = 0.2
node_delete_prob = 0.2
# network parameters
num_hidden = 0
num_inputs = 2
num_outputs = 1
# node response options
response_init_mean = 1.0
response_init_stdev = 0.0
response_max_value = 30.0
response_min_value = -30.0
response_mutate_power = 0.0
response_mutate_rate = 0.0
response_replace_rate = 0.0
# connection weight options
weight_init_mean = 0.0
weight_init_stdev = 1.0
weight_max_value = 30
weight_min_value = -30
weight_mutate_power = 0.5
weight_mutate_rate = 0.8
weight_replace_rate = 0.1
[DefaultSpeciesSet]
compatibility_threshold = 3.0
[DefaultStagnation]
species_fitness_func = max
max_stagnation = 20
species_elitism = 2
[DefaultReproduction]
elitism = 2
survival_threshold = 0.2
Lastly here is the version of python-neat I have installed
pip show neat-python
Name: neat-python
Version: 0.92
Summary: A NEAT (NeuroEvolution of Augmenting Topologies) implementation
Home-page: https://github.com/CodeReclaimers/neat-python
Could anyone please help me resolve the following error? Because so far what I have tried is installing from github and installing from pip and both give me the same error on the example code. I have also tried variant code but i get the same error.
****** Running generation 0 ******
Traceback (most recent call last):
File "driver.py", line 34, in <module>
winner = p.run(eval_genomes)
File "/home/j/anaconda3/lib/python3.8/site-packages/neat_python-0.92-py3.8.egg/neat/population.py", line 88, in run
File "driver.py", line 18, in eval_genomes
output = net.activate(xi)
File "/home/j/anaconda3/lib/python3.8/site-packages/neat_python-0.92-py3.8.egg/neat/nn/feed_forward.py", line 13, in activate
RuntimeError: Expected 3 inputs, got 2
You are using an example code for a newer version.
Example Source
NOTE: This page shows the source and configuration file for the current version of neat-python available on GitHub. If you are using the version 0.92 installed from PyPI, make sure you get the script and config file from the archived source for that release.
I checked your code in the https://neat-python.readthedocs.io/en/latest/xor_example.html and it looks the same but check your version. Try to access the archived source for that release:
https://github.com/CodeReclaimers/neat-python/releases/tag/v0.92
if __name__ == '__main__':
# Determine path to configuration file. This path manipulation is
# here so that the script will run successfully regardless of the
# current working directory.
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward') #<----
run(config_path)
in this "if" you will change the name of the config file as 'config-feedforward.txt' instead of 'config-feedforward'

Getting error in CUPS "The page setup information was not valid." with printing image from python script

I try to print an image from python script on Debian 10 using cups:
import cups
def printImageLinux(image_name):
conn = cups.Connection()
printer = conn.getDefault()
conn.printFile(printer, image_name, 'suo_ticket', {})
Finally, the image went to print but I see canceling of printing and error in Cups user interface (localhost:631) with a message:
"The page setup information was not valid."
CUPS message screenshot
I suppose that I should make some preparation of image sending to print, but I didn't find any information about it.
I can print the same image from Windows using win32print module and code:
import os, sys
from win32 import win32api, win32print
from PIL import Image, ImageWin
def printImage(image_name):
# Constants for GetDeviceCaps
# HORZRES / VERTRES = printable area
HORZRES = 8
VERTRES = 10
# LOGPIXELS = dots per inch
LOGPIXELSX = 88
LOGPIXELSY = 90
# PHYSICALWIDTH/HEIGHT = total area
PHYSICALWIDTH = 110
PHYSICALHEIGHT = 111
# PHYSICALOFFSETX/Y = left / top margin
PHYSICALOFFSETX = 112
PHYSICALOFFSETY = 113
printer_name = win32print.GetDefaultPrinter ()
file_name = image_name
#
# You can only write a Device-independent bitmap
# directly to a Windows device context; therefore
# we need (for ease) to use the Python Imaging
# Library to manipulate the image.
#
# Create a device context from a named printer
# and assess the printable size of the paper.
#
hDC = win32ui.CreateDC ()
hDC.CreatePrinterDC (printer_name)
printable_area = hDC.GetDeviceCaps (HORZRES), hDC.GetDeviceCaps (VERTRES)
printer_size = hDC.GetDeviceCaps (PHYSICALWIDTH), hDC.GetDeviceCaps (PHYSICALHEIGHT)
printer_margins = hDC.GetDeviceCaps (PHYSICALOFFSETX), hDC.GetDeviceCaps (PHYSICALOFFSETY)
#
# Open the image, rotate it if it's wider than
# it is high, and work out how much to multiply
# each pixel by to get it as big as possible on
# the page without distorting.
#
bmp = Image.open (file_name)
if bmp.size[0] > bmp.size[1]:
bmp = bmp.rotate (90)
ratios = [1.0 * printable_area[0] / bmp.size[0], 1.0 * printable_area[1] / bmp.size[1]]
scale = min (ratios)
#
# Start the print job, and draw the bitmap to
# the printer device at the scaled size.
#
hDC.StartDoc (file_name)
hDC.StartPage ()
dib = ImageWin.Dib (bmp)
scaled_width, scaled_height = [int (scale * i) for i in bmp.size]
x1 = int ((printer_size[0] - scaled_width) / 2)
y1 = int ((printer_size[1] - scaled_height) / 2)
x2 = x1 + scaled_width
y2 = y1 + scaled_height
dib.draw (hDC.GetHandleOutput (), (x1, y1, x2, y2))
hDC.EndPage ()
hDC.EndDoc ()
hDC.DeleteDC ()
It works correctly.
Can I make the same operations with the image in Debian?
Thank you for any help!
Problem was solved with using PIL module. Working code:
import cups
from PIL import Image
def printImageLinux(image_name):
conn = cups.Connection()
printer = conn.getDefault()
image1 = Image.open(image_name)
im1 = image1.convert('RGB')
im1.save('temp_image.pdf')
conn.printFile(printer, 'temp_image.pdf', 'suo_ticket', {'fit-to-page':'True'})

How to make lottie animation of image sequance by python?

I am trying to make animation using lottie frame work in python. The script I have made can show only one image. I don't know how to animate image sequence in lottie frame work by python. Any help would be appreciated.
from lottie.utils import script
from lottie import objects
from lottie import Point, Color
import os
image_filename1 = os.path.dirname(os.path.realpath(__file__))+'/images1/pngImages'+'/'+'2020-05-01'+"_new.png"
last_frame = 60
an = objects.Animation(last_frame, 1)
an.width = 720
an.height = 360
image1 = objects.assets.Image().load(image_filename1)
an.assets.append(image1)
an.add_layer(objects.ImageLayer(image1.id))
script.script_main(an, path="/Users/ihasan/", basename='sample2', formats=['html'])
After searching on the lottie-python examples script here, I found a way to animate image sequence. The code I am sharing here is composed of two image. It can be simplified using a loop with more image.
from lottie.utils import script
from lottie import objects
from lottie import Point, Color
import os
image_filename1 = "/../" # image1 directory
image_filename2 = "/../" # image2 directory
image1 = objects.assets.Image().load(image_filename1)
image2 = objects.assets.Image().load(image_filename2)
lastFrame = 60
an = objects.Animation(lastFrame)
an.width = 720
an.height = 360
an.assets.append(image1)
an.assets.append(image2)
precomp = objects.Precomp("myid", an)
layer1 = objects.ImageLayer(image1.id)
layer1.out_point = 20
precomp.add_layer(layer1)
pcl0 = an.add_layer(objects.PreCompLayer("myid"))
pcl0.width = 720
pcl0.height = 360
pcl0.start_time = 0
layer2 = objects.ImageLayer(image2.id)
layer2.out_point = 40
precomp.add_layer(layer2)
pcl1 = an.add_layer(objects.PreCompLayer("myid"))
pcl1.start_time = 20
pcl1.width = 720
pcl0.height = 360
script.script_main(an, path="../../", basename='samplePrecomp', formats=['json'])

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