3
$\begingroup$

I want to make my two sided (input model is collada). so, for that i want to duplicate all the faces in edit mode and then flip normals, and then export the model as fbx. i want to do this using python script.

my command to run the python script is

blender --background --python MeshDuplicate.py

Below is the .py file i am calling:

import bpy
import sys

object = bpy.ops.wm.collada_import(filepath="H:\\models\\armour.dae")
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.mesh.select_all(action='SELECT')
dup_object = bpy.data.objects.get("object")
object_d = dup_object.copy()
object_d.data = object.data.copy()
scene = bpy.context.scene
scene.objects.link(dup_object)
scene.update()  
bpy.ops.export_scene.fbx(filepath="H:\\models\\armour.fbx", axis_forward='-Z', axis_up='Y')

i am getting this error.

Read new prefs: C:\Users\Lee\AppData\Roaming\Blender Foundation\Blender\2.76\config\userpref.blend AL lib: (EE) UpdateDeviceParams: Failed to set 44100hz, got 96000hz instead found bundled python: C:\Program Files\Blender Foundation\Blender\2.76\python Writing node id='node', name='node' Traceback (most recent call last): File "", line 2, in File "C:\Program Files\Blender Foundation\Blender\MeshDuplicate_Flip.py", line 11, in object_d = dup_object.copy() AttributeError: 'NoneType' object has no attribute 'copy'

$\endgroup$

2 Answers 2

2
$\begingroup$

Operators return a set

Operators return a status in a set. If the operator has worked it returns {'FINISHED'} and if cancelled {'CANCELLED'}

Hence in this line

object = bpy.ops.wm.collada_import(filepath="H:\\models\\armour.dae")

if the import succeeded the return value is {'FINISHED'} Note object is a python built in, the basic python object type, and is best not used as a variable

As answered by @Crantisz the error occurs because your dup_obj is None Unless there is an object in the blend named "object"... ..unlikely??

dup_object = bpy.data.objects.get("object")

Note: there is no correlation between having a variable named "object" and there being a blender object named "object".

Alternative method

After an import operator has run succesfully, most importers set the newly imported objects as selected and one as active. Test this by checking in UI for different importers, This is recommended default behaviour.

After a successful import the active object is

# straight after import operator
#active_newly_imported object_

ob = context.object
# list of all newly imported objects
imported_obs = context.selected_objects

Using bmesh to flip normals removes the need for edit mode toggling required to use the mesh operator.

Test script (untested). After import, Read each newly imported mesh object into a bmesh, flip the normals, write back to mesh... rinse repeat.

import bpy
import bmesh
context = bpy.context 
bm = bmesh.new()
bpy.ops.wm.collada_import(filepath="H:\\models\\armour.dae")
meshobjs = [o for o in context.selected_objects if o.type=='MESH']
for ob in meshobjs:
    me = ob.data
    bm.from_mesh(me) # load bmesh
    for f in bm.faces:
        f.normal_flip()
    bm.normal_update() # not sure if req'd
    bm.to_mesh(me)
    me.update()
    bm.clear() #.. clear before load next
    
bpy.ops.export_scene.fbx(
        filepath="H:\\models\\armour.fbx", 
        axis_forward='-Z', 
        axis_up='Y')

Finally there could be a chance your axis transformation inverts scale which can also produce flipped normals.

$\endgroup$
1
  • $\begingroup$ is there any way to also flip custom normals using bmesh or any other technique? Since a few Blender versions there is bpy.context.object.data.flip_normals(), which produces the same result as your script above, but both approaches don't flip custom normals correctly. Only bpy.ops.mesh.flip_normals() gives the result I'd want. $\endgroup$
    – aliasguru
    Mar 29, 2022 at 15:35
1
$\begingroup$

Then you get this error

'NoneType' object has no attribute 'copy'

This means, that you try to get attribute from object 'NoneType'. NoneType is nothing. So you want to get something from none. Why dup_object is None? You will get 'NoneType' when try to get object, that doesn't exists. I guess there is no object with name ""object"". Why name is "object"? - check this.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .