glTF: fix a few typos #104607

Merged
Julien Duroure merged 2 commits from pioverfour/blender-addons:dp_gltf_typos into blender-v3.6-release 2023-05-22 14:26:42 +02:00
8 changed files with 174 additions and 168 deletions
Showing only changes of commit 293ae716f7 - Show all commits

View File

@ -2,12 +2,12 @@
# #
# #
# Author : Clemens Barth (Blendphys@root-1.de) # Author : Clemens Barth (Blendphys@root-1.de)
# Homepage(Wiki) : http://development.root-1.de/Atomic_Blender.php # Homepage(Wiki) : https://docs.blender.org/manual/en/dev/addons/import_export/mesh_atomic.html
# #
# Start of project : 2011-08-31 by CB # Start of project : 2011-08-31 by CB
# First publication in Blender : 2011-11-11 by CB # First publication in Blender : 2011-11-11 by CB
# Fusion of the PDB, XYZ and Panel : 2019-03-22 by CB # Fusion of the PDB, XYZ and Panel : 2019-03-22 by CB
# Last modified : 2019-05-17 # Last modified : 2023-05-19
# #
# Contributing authors # Contributing authors
# ==================== # ====================

View File

@ -96,8 +96,8 @@ class IMPORT_OT_pdb(Operator, ImportHelper):
name="Bonds", default=False, name="Bonds", default=False,
description="Show double and triple bonds") description="Show double and triple bonds")
sticks_dist: FloatProperty( sticks_dist: FloatProperty(
name="", default = 1.1, min=1.0, max=3.0, name="", default = 0.8, min=0.0, max=3.0,
description="Distance between sticks measured in stick diameter") description="Distance between sticks (double or tripple bonds) measured in stick diameter")
use_sticks_one_object: BoolProperty( use_sticks_one_object: BoolProperty(
name="One object", default=False, name="One object", default=False,
description="All sticks are one object") description="All sticks are one object")
@ -184,7 +184,10 @@ class IMPORT_OT_pdb(Operator, ImportHelper):
col = row.column() col = row.column()
col.active = self.use_sticks_one_object col.active = self.use_sticks_one_object
col.prop(self, "use_sticks_one_object_nr") col.prop(self, "use_sticks_one_object_nr")
row = box.row()
row.active = self.use_sticks and self.use_sticks_bonds
row.label(text="Distance")
row.prop(self, "sticks_dist")
def execute(self, context): def execute(self, context):
# Switch to 'OBJECT' mode when in 'EDIT' mode. # Switch to 'OBJECT' mode when in 'EDIT' mode.

View File

@ -556,7 +556,7 @@ def camera_light_source(use_camera,
camera_factor = 15.0 camera_factor = 15.0
# If chosen a camera is put into the scene. # If chosen, a camera is put into the scene.
if use_camera == True: if use_camera == True:
# Assume that the object is put into the global origin. Then, the # Assume that the object is put into the global origin. Then, the
@ -850,7 +850,7 @@ def draw_sticks_dupliverts(all_atoms,
i = 0 i = 0
# What follows is school mathematics! :-) We construct equidistant # What follows is school mathematics! :-) We construct equidistant
# planes, on which the stcik sections (cylinders) are perpendicular on. # planes, on which the stick sections (cylinders) are perpendicular on.
for stick in stick_list: for stick in stick_list:
dv = stick[2] dv = stick[2]
@ -1100,6 +1100,7 @@ def draw_sticks_normal(all_atoms,
center, center,
Stick_diameter, Stick_diameter,
Stick_sectors, Stick_sectors,
Stick_dist,
use_sticks_smooth, use_sticks_smooth,
use_sticks_one_object, use_sticks_one_object,
use_sticks_one_object_nr, use_sticks_one_object_nr,
@ -1117,52 +1118,96 @@ def draw_sticks_normal(all_atoms,
list_group = [] list_group = []
list_group_sub = [] list_group_sub = []
counter = 0 counter = 0
for stick in all_sticks: for i, stick in enumerate(all_sticks):
# We treat here single, double and tripple bonds: stick.number <= 3
for repeat in range(stick.number):
# The vectors of the two atoms # The vectors of the two atoms
atom1 = all_atoms[stick.atom1-1].location-center atom1 = copy(all_atoms[stick.atom1-1].location)-center
atom2 = all_atoms[stick.atom2-1].location-center atom2 = copy(all_atoms[stick.atom2-1].location)-center
# Location
dist = Stick_diameter * Stick_dist
# The two sticks are on the left and right of the middle connection.
if stick.number == 2:
if repeat == 0:
atom1 += (stick.dist * dist)
atom2 += (stick.dist * dist)
if repeat == 1:
atom1 -= (stick.dist * dist)
atom2 -= (stick.dist * dist)
if stick.number == 3:
if repeat == 0:
atom1 += (stick.dist * dist)
atom2 += (stick.dist * dist)
if repeat == 2:
atom1 -= (stick.dist * dist)
atom2 -= (stick.dist * dist)
# Vector pointing along the stick direction
dv = atom1 - atom2
# The normalized vector of this, with lenght 1
n = dv / dv.length
# Starting point of the stick
location = (atom1 + atom2) * 0.5 location = (atom1 + atom2) * 0.5
# The difference of both vectors
v = (atom2 - atom1)
# Angle with respect to the z-axis # Angle with respect to the z-axis
angle = v.angle(up_axis, 0) angle = dv.angle(up_axis, 0)
# Cross-product between v and the z-axis vector. It is the # Cross-product between v and the z-axis vector. It is the
# vector of rotation. # vector of rotation.
axis = up_axis.cross(v) axis = up_axis.cross(dv)
# Calculate Euler angles # Calculate Euler angles
euler = Matrix.Rotation(angle, 4, axis).to_euler() euler = Matrix.Rotation(angle, 4, axis).to_euler()
# Create stick # Create stick
stick = bpy.ops.mesh.primitive_cylinder_add(vertices=Stick_sectors, stick_obj = bpy.ops.mesh.primitive_cylinder_add(vertices=Stick_sectors,
radius=Stick_diameter, radius=Stick_diameter,
depth=v.length, depth=dv.length,
end_fill_type='NGON', end_fill_type='NGON',
align='WORLD', align='WORLD',
enter_editmode=False, enter_editmode=False,
location=location, location=location,
rotation=(0, 0, 0)) rotation=(0, 0, 0))
# Put the stick into the scene ... # Put the stick into the scene ...
stick = bpy.context.view_layer.objects.active stick_obj = bpy.context.view_layer.objects.active
# ... and rotate the stick. # ... and rotate the stick.
stick.rotation_euler = euler stick_obj.rotation_euler = euler
# ... and name # ... and name
stick.name = "Stick_Cylinder" if stick.number == 1:
stick_obj.name = "Stick_Cylinder_%04d" %(i)
elif stick.number == 2:
if repeat == 0:
stick_obj.name = "Stick_Cylinder_%04d" %(i) + "_left"
elif repeat == 1:
stick_obj.name = "Stick_Cylinder_%04d" %(i) + "_right"
elif stick.number == 3:
if repeat == 0:
stick_obj.name = "Stick_Cylinder_%04d" %(i) + "_left"
elif repeat == 1:
stick_obj.name = "Stick_Cylinder_%04d" %(i) + "_middle"
elif repeat == 2:
stick_obj.name = "Stick_Cylinder_%04d" %(i) + "_right"
# Never occurs:
else:
stick_obj.name = "Stick_Cylinder"
# Never occurs:
else:
stick_obj.name = "Stick_Cylinder"
counter += 1 counter += 1
# Smooth the cylinder. # Smooth the cylinder.
if use_sticks_smooth == True: if use_sticks_smooth == True:
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
stick.select_set(True) stick_obj.select_set(True)
bpy.ops.object.shade_smooth() bpy.ops.object.shade_smooth()
list_group_sub.append(stick) list_group_sub.append(stick_obj)
if use_sticks_one_object == True: if use_sticks_one_object == True:
if counter == use_sticks_one_object_nr: if counter == use_sticks_one_object_nr:
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
for stick in list_group_sub: for stick_select in list_group_sub:
stick.select_set(True) stick_select.select_set(True)
bpy.ops.object.join() bpy.ops.object.join()
list_group.append(bpy.context.view_layer.objects.active) list_group.append(bpy.context.view_layer.objects.active)
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
@ -1170,7 +1215,7 @@ def draw_sticks_normal(all_atoms,
counter = 0 counter = 0
else: else:
# Material ... # Material ...
stick.active_material = stick_material stick_obj.active_material = stick_material
if use_sticks_one_object == True: if use_sticks_one_object == True:
bpy.ops.object.select_all(action='DESELECT') bpy.ops.object.select_all(action='DESELECT')
@ -1531,6 +1576,7 @@ def import_pdb(Ball_type,
object_center_vec, object_center_vec,
Stick_diameter, Stick_diameter,
Stick_sectors, Stick_sectors,
Stick_dist,
use_sticks_smooth, use_sticks_smooth,
use_sticks_one_object, use_sticks_one_object,
use_sticks_one_object_nr, use_sticks_one_object_nr,

View File

@ -157,7 +157,7 @@ def sane_name(name):
new_name = new_name_clean + '.%.3d' % i new_name = new_name_clean + '.%.3d' % i
i += 1 i += 1
# note, appending the 'str' version. # note, appending the 'str' version
name_unique.append(new_name) name_unique.append(new_name)
name_mapping[name] = new_name = new_name.encode("ASCII", "replace") name_mapping[name] = new_name = new_name.encode("ASCII", "replace")
return new_name return new_name
@ -166,14 +166,13 @@ def sane_name(name):
def uv_key(uv): def uv_key(uv):
return round(uv[0], 6), round(uv[1], 6) return round(uv[0], 6), round(uv[1], 6)
# size defines: # size defines
SZ_SHORT = 2 SZ_SHORT = 2
SZ_INT = 4 SZ_INT = 4
SZ_FLOAT = 4 SZ_FLOAT = 4
class _3ds_ushort(object): class _3ds_ushort(object):
"""Class representing a short (2-byte integer) for a 3ds file. """Class representing a short (2-byte integer) for a 3ds file."""
*** This looks like an unsigned short H is unsigned from the struct docs - Cam***"""
__slots__ = ("value", ) __slots__ = ("value", )
def __init__(self, val=0): def __init__(self, val=0):
@ -308,7 +307,7 @@ class _3ds_float_color(object):
return 3 * SZ_FLOAT return 3 * SZ_FLOAT
def write(self, file): def write(self, file):
file.write(struct.pack('3f', self.r, self.g, self.b)) file.write(struct.pack('<3f', self.r, self.g, self.b))
def __str__(self): def __str__(self):
return '{%f, %f, %f}' % (self.r, self.g, self.b) return '{%f, %f, %f}' % (self.r, self.g, self.b)
@ -342,9 +341,7 @@ class _3ds_face(object):
def get_size(self): def get_size(self):
return 4 * SZ_SHORT return 4 * SZ_SHORT
# no need to validate every face vert. the oversized array will # no need to validate every face vert, the oversized array will catch this problem
# catch this problem
def write(self, file): def write(self, file):
# The last short is used for face flags # The last short is used for face flags
file.write(struct.pack('<4H', self.vindex[0], self.vindex[1], self.vindex[2], self.flag)) file.write(struct.pack('<4H', self.vindex[0], self.vindex[1], self.vindex[2], self.flag))
@ -355,15 +352,14 @@ class _3ds_face(object):
class _3ds_array(object): class _3ds_array(object):
"""Class representing an array of variables for a 3ds file. """Class representing an array of variables for a 3ds file.
Consists of a _3ds_ushort to indicate the number of items, followed by the items themselves. Consists of a _3ds_ushort to indicate the number of items, followed by the items themselves."""
"""
__slots__ = "values", "size" __slots__ = "values", "size"
def __init__(self): def __init__(self):
self.values = [] self.values = []
self.size = SZ_SHORT self.size = SZ_SHORT
# add an item: # add an item
def add(self, item): def add(self, item):
self.values.append(item) self.values.append(item)
self.size += item.get_size() self.size += item.get_size()
@ -380,7 +376,7 @@ class _3ds_array(object):
value.write(file) value.write(file)
# To not overwhelm the output in a dump, a _3ds_array only # To not overwhelm the output in a dump, a _3ds_array only
# outputs the number of items, not all of the actual items. # outputs the number of items, not all of the actual items
def __str__(self): def __str__(self):
return '(%d items)' % len(self.values) return '(%d items)' % len(self.values)
@ -583,7 +579,7 @@ def make_material_texture_chunk(chunk_id, texslots, pct):
0x40 activates alpha source, 0x80 activates tinting, 0x100 ignores alpha, 0x200 activates RGB tint. 0x40 activates alpha source, 0x80 activates tinting, 0x100 ignores alpha, 0x200 activates RGB tint.
Bits 0x80, 0x100, and 0x200 are only used with TEXMAP, TEX2MAP, and SPECMAP chunks. Bits 0x80, 0x100, and 0x200 are only used with TEXMAP, TEX2MAP, and SPECMAP chunks.
0x40, when used with a TEXMAP, TEX2MAP, or SPECMAP chunk must be accompanied with a tint bit, 0x40, when used with a TEXMAP, TEX2MAP, or SPECMAP chunk must be accompanied with a tint bit,
either 0x100 or 0x200, tintcolor will be processed if colorchunks are present""" either 0x100 or 0x200, tintcolor will be processed if tintflags are present"""
mapflags = 0 mapflags = 0
if texslot.extension == 'EXTEND': if texslot.extension == 'EXTEND':
@ -632,9 +628,8 @@ def make_material_texture_chunk(chunk_id, texslots, pct):
rgb.add_variable("mapcolor", _3ds_rgb_color(spec if texslot.socket_dst.identifier == 'Specular' else base)) rgb.add_variable("mapcolor", _3ds_rgb_color(spec if texslot.socket_dst.identifier == 'Specular' else base))
mat_sub.add_subchunk(rgb) mat_sub.add_subchunk(rgb)
# store all textures for this mapto in order. This at least is what # store all textures for this mapto in order. This at least is what the
# the 3DS exporter did so far, afaik most readers will just skip # 3DS exporter did so far, afaik most readers will just skip over 2nd textures
# over 2nd textures.
for slot in texslots: for slot in texslots:
if slot.image is not None: if slot.image is not None:
add_texslot(slot) add_texslot(slot)
@ -685,9 +680,9 @@ def make_material_chunk(material, image):
primary_tex = False primary_tex = False
if wrap.base_color_texture: if wrap.base_color_texture:
d_pct = 0.7 + sum(wrap.base_color[:]) * 0.1
color = [wrap.base_color_texture] color = [wrap.base_color_texture]
matmap = make_material_texture_chunk(MAT_DIFFUSEMAP, color, d_pct) c_pct = 0.7 + sum(wrap.base_color[:]) * 0.1
matmap = make_material_texture_chunk(MAT_DIFFUSEMAP, color, c_pct)
if matmap: if matmap:
material_chunk.add_subchunk(matmap) material_chunk.add_subchunk(matmap)
primary_tex = True primary_tex = True
@ -729,8 +724,8 @@ def make_material_chunk(material, image):
material_chunk.add_subchunk(matmap) material_chunk.add_subchunk(matmap)
if wrap.emission_color_texture: if wrap.emission_color_texture:
e_pct = wrap.emission_strength
emission = [wrap.emission_color_texture] emission = [wrap.emission_color_texture]
e_pct = wrap.emission_strength
matmap = make_material_texture_chunk(MAT_SELFIMAP, emission, e_pct) matmap = make_material_texture_chunk(MAT_SELFIMAP, emission, e_pct)
if matmap: if matmap:
material_chunk.add_subchunk(matmap) material_chunk.add_subchunk(matmap)
@ -849,8 +844,7 @@ def remove_face_uv(verts, tri_list):
need to be converted to vertex uv coordinates. That means that vertices need to be duplicated when need to be converted to vertex uv coordinates. That means that vertices need to be duplicated when
there are multiple uv coordinates per vertex.""" there are multiple uv coordinates per vertex."""
# initialize a list of UniqueLists, one per vertex: # initialize a list of UniqueLists, one per vertex
# uv_list = [UniqueList() for i in xrange(len(verts))]
unique_uvs = [{} for i in range(len(verts))] unique_uvs = [{} for i in range(len(verts))]
# for each face uv coordinate, add it to the UniqueList of the vertex # for each face uv coordinate, add it to the UniqueList of the vertex
@ -861,7 +855,6 @@ def remove_face_uv(verts, tri_list):
context_uv_vert = unique_uvs[tri.vertex_index[i]] context_uv_vert = unique_uvs[tri.vertex_index[i]]
uvkey = tri.faceuvs[i] uvkey = tri.faceuvs[i]
offset_index__uv_3ds = context_uv_vert.get(uvkey) offset_index__uv_3ds = context_uv_vert.get(uvkey)
if not offset_index__uv_3ds: if not offset_index__uv_3ds:
@ -869,11 +862,9 @@ def remove_face_uv(verts, tri_list):
tri.offset[i] = offset_index__uv_3ds[0] tri.offset[i] = offset_index__uv_3ds[0]
# At this point, each vertex has a UniqueList containing every uv coordinate that is associated with it # At this point, each vertex has a UniqueList containing every uv coordinate associated with it only once
# only once.
# Now we need to duplicate every vertex as many times as it has uv coordinates and make sure the # Now we need to duplicate every vertex as many times as it has uv coordinates and make sure the
# faces refer to the new face indices: # faces refer to the new face indices
vert_index = 0 vert_index = 0
vert_array = _3ds_array() vert_array = _3ds_array()
uv_array = _3ds_array() uv_array = _3ds_array()
@ -884,22 +875,21 @@ def remove_face_uv(verts, tri_list):
pt = _3ds_point_3d(vert.co) # reuse, should be ok pt = _3ds_point_3d(vert.co) # reuse, should be ok
uvmap = [None] * len(unique_uvs[i]) uvmap = [None] * len(unique_uvs[i])
for ii, uv_3ds in unique_uvs[i].values(): for ii, uv_3ds in unique_uvs[i].values():
# add a vertex duplicate to the vertex_array for every uv associated with this vertex: # add a vertex duplicate to the vertex_array for every uv associated with this vertex
vert_array.add(pt) vert_array.add(pt)
# add the uv coordinate to the uv array: # add the uv coordinate to the uv array, this for loop does not give
# This for loop does not give uv's ordered by ii, so we create a new map # uv's ordered by ii, so we create a new map and add the uv's later
# and add the uv's later
# uv_array.add(uv_3ds) # uv_array.add(uv_3ds)
uvmap[ii] = uv_3ds uvmap[ii] = uv_3ds
# Add the uv's in the correct order # Add the uv's in the correct order
for uv_3ds in uvmap: for uv_3ds in uvmap:
# add the uv coordinate to the uv array: # add the uv coordinate to the uv array
uv_array.add(uv_3ds) uv_array.add(uv_3ds)
vert_index += len(unique_uvs[i]) vert_index += len(unique_uvs[i])
# Make sure the triangle vertex indices now refer to the new vertex list: # Make sure the triangle vertex indices now refer to the new vertex list
for tri in tri_list: for tri in tri_list:
for i in range(3): for i in range(3):
tri.offset[i] += index_list[tri.vertex_index[i]] tri.offset[i] += index_list[tri.vertex_index[i]]
@ -1003,30 +993,30 @@ def make_uv_chunk(uv_array):
def make_mesh_chunk(ob, mesh, matrix, materialDict, translation): def make_mesh_chunk(ob, mesh, matrix, materialDict, translation):
"""Make a chunk out of a Blender mesh.""" """Make a chunk out of a Blender mesh."""
# Extract the triangles from the mesh: # Extract the triangles from the mesh
tri_list = extract_triangles(mesh) tri_list = extract_triangles(mesh)
if mesh.uv_layers: if mesh.uv_layers:
# Remove the face UVs and convert it to vertex UV: # Remove the face UVs and convert it to vertex UV
vert_array, uv_array, tri_list = remove_face_uv(mesh.vertices, tri_list) vert_array, uv_array, tri_list = remove_face_uv(mesh.vertices, tri_list)
else: else:
# Add the vertices to the vertex array: # Add the vertices to the vertex array
vert_array = _3ds_array() vert_array = _3ds_array()
for vert in mesh.vertices: for vert in mesh.vertices:
vert_array.add(_3ds_point_3d(vert.co)) vert_array.add(_3ds_point_3d(vert.co))
# no UV at all: # no UV at all
uv_array = None uv_array = None
# create the chunk: # create the chunk
mesh_chunk = _3ds_chunk(OBJECT_MESH) mesh_chunk = _3ds_chunk(OBJECT_MESH)
# add vertex chunk: # add vertex chunk
mesh_chunk.add_subchunk(make_vert_chunk(vert_array)) mesh_chunk.add_subchunk(make_vert_chunk(vert_array))
# add faces chunk: # add faces chunk
mesh_chunk.add_subchunk(make_faces_chunk(tri_list, mesh, materialDict)) mesh_chunk.add_subchunk(make_faces_chunk(tri_list, mesh, materialDict))
# if available, add uv chunk: # if available, add uv chunk
if uv_array: if uv_array:
mesh_chunk.add_subchunk(make_uv_chunk(uv_array)) mesh_chunk.add_subchunk(make_uv_chunk(uv_array))
@ -1200,15 +1190,15 @@ def save(operator,
if bpy.ops.object.mode_set.poll(): if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
# Initialize the main chunk (primary): # Initialize the main chunk (primary)
primary = _3ds_chunk(PRIMARY) primary = _3ds_chunk(PRIMARY)
# Add version chunk: # Add version chunk
version_chunk = _3ds_chunk(VERSION) version_chunk = _3ds_chunk(VERSION)
version_chunk.add_variable("version", _3ds_uint(3)) version_chunk.add_variable("version", _3ds_uint(3))
primary.add_subchunk(version_chunk) primary.add_subchunk(version_chunk)
# Init main object info chunk: # Init main object info chunk
object_info = _3ds_chunk(OBJECTINFO) object_info = _3ds_chunk(OBJECTINFO)
mesh_version = _3ds_chunk(MESHVERSION) mesh_version = _3ds_chunk(MESHVERSION)
mesh_version.add_variable("mesh", _3ds_uint(3)) mesh_version.add_variable("mesh", _3ds_uint(3))
@ -1233,7 +1223,7 @@ def save(operator,
''' '''
# Make a list of all materials used in the selected meshes (use a dictionary, # Make a list of all materials used in the selected meshes (use a dictionary,
# each material is added once): # each material is added once)
materialDict = {} materialDict = {}
mesh_objects = [] mesh_objects = []
@ -1270,7 +1260,7 @@ def save(operator,
ma_ls = data.materials ma_ls = data.materials
ma_ls_len = len(ma_ls) ma_ls_len = len(ma_ls)
# get material/image tuples. # get material/image tuples
if data.uv_layers: if data.uv_layers:
if not ma_ls: if not ma_ls:
ma = ma_name = None ma = ma_name = None
@ -1291,7 +1281,7 @@ def save(operator,
else: else:
for ma in ma_ls: for ma in ma_ls:
if ma: # material may be None so check its not. if ma: # material may be None so check its not
materialDict.setdefault((ma.name, None), (ma, None)) materialDict.setdefault((ma.name, None), (ma, None))
# Why 0 Why! # Why 0 Why!
@ -1300,14 +1290,14 @@ def save(operator,
f.material_index = 0 f.material_index = 0
# Make material chunks for all materials used in the meshes: # Make material chunks for all materials used in the meshes
for ma_image in materialDict.values(): for ma_image in materialDict.values():
object_info.add_subchunk(make_material_chunk(ma_image[0], ma_image[1])) object_info.add_subchunk(make_material_chunk(ma_image[0], ma_image[1]))
# Collect translation for transformation matrix # Collect translation for transformation matrix
translation = {} translation = {}
# Give all objects a unique ID and build a dictionary from object name to object id: # Give all objects a unique ID and build a dictionary from object name to object id
# name_to_id = {} # name_to_id = {}
for ob, data, matrix in mesh_objects: for ob, data, matrix in mesh_objects:
@ -1318,7 +1308,7 @@ def save(operator,
translation[ob.name] = ob.location translation[ob.name] = ob.location
# name_to_id[ob.name]= len(name_to_id) # name_to_id[ob.name]= len(name_to_id)
# Create object chunks for all meshes: # Create object chunks for all meshes
i = 0 i = 0
for ob, mesh, matrix in mesh_objects: for ob, mesh, matrix in mesh_objects:
# create a new object chunk # create a new object chunk
@ -1327,12 +1317,11 @@ def save(operator,
# set the object name # set the object name
object_chunk.add_variable("name", _3ds_string(sane_name(ob.name))) object_chunk.add_variable("name", _3ds_string(sane_name(ob.name)))
# make a mesh chunk out of the mesh: # make a mesh chunk out of the mesh
object_chunk.add_subchunk(make_mesh_chunk(ob, mesh, matrix, materialDict, translation)) object_chunk.add_subchunk(make_mesh_chunk(ob, mesh, matrix, materialDict, translation))
# ensure the mesh has no over sized arrays # Ensure the mesh has no over sized arrays, skip ones that do!
# skip ones that do!, otherwise we cant write since the array size wont # Otherwise we cant write since the array size wont fit into USHORT
# fit into USHORT.
if object_chunk.validate(): if object_chunk.validate():
object_info.add_subchunk(object_chunk) object_info.add_subchunk(object_chunk)
else: else:
@ -1345,7 +1334,7 @@ def save(operator,
i += i i += i
# Create chunks for all empties: # Create chunks for all empties
''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
for ob in empty_objects: for ob in empty_objects:
# Empties only require a kf object node: # Empties only require a kf object node:
@ -1408,7 +1397,7 @@ def save(operator,
object_chunk.add_subchunk(camera_chunk) object_chunk.add_subchunk(camera_chunk)
object_info.add_subchunk(object_chunk) object_info.add_subchunk(object_chunk)
# Add main object info chunk to primary chunk: # Add main object info chunk to primary chunk
primary.add_subchunk(object_info) primary.add_subchunk(object_info)
''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
@ -1416,27 +1405,27 @@ def save(operator,
primary.add_subchunk(kfdata) primary.add_subchunk(kfdata)
''' '''
# At this point, the chunk hierarchy is completely built. # At this point, the chunk hierarchy is completely built
# Check the size: # Check the size
primary.get_size() primary.get_size()
# Open the file for writing: # Open the file for writing
file = open(filepath, 'wb') file = open(filepath, 'wb')
# Recursively write the chunks to file: # Recursively write the chunks to file
primary.write(file) primary.write(file)
# Close the file: # Close the file
file.close() file.close()
# Clear name mapping vars, could make locals too # Clear name mapping vars, could make locals too
del name_unique[:] del name_unique[:]
name_mapping.clear() name_mapping.clear()
# Debugging only: report the exporting time: # Debugging only: report the exporting time
print("3ds export time: %.2f" % (time.time() - duration)) print("3ds export time: %.2f" % (time.time() - duration))
# Debugging only: dump the chunk hierarchy: # Debugging only: dump the chunk hierarchy
# primary.dump() # primary.dump()
return {'FINISHED'} return {'FINISHED'}

View File

@ -16,7 +16,7 @@
bl_info = { bl_info = {
"name": "Sun Position", "name": "Sun Position",
"author": "Michael Martin, Damien Picard", "author": "Michael Martin, Damien Picard",
"version": (3, 5, 0), "version": (3, 5, 2),
"blender": (3, 2, 0), "blender": (3, 2, 0),
"location": "World > Sun Position", "location": "World > Sun Position",
"description": "Show sun position with objects and/or sky texture", "description": "Show sun position with objects and/or sky texture",

View File

@ -10,34 +10,8 @@ from mathutils import Vector
from math import sqrt, pi, atan2, asin from math import sqrt, pi, atan2, asin
vertex_shader = ''' image_shader = gpu.shader.from_builtin('2D_IMAGE_COLOR')
uniform mat4 ModelViewProjectionMatrix; line_shader = gpu.shader.from_builtin('2D_FLAT_COLOR')
/* Keep in sync with intern/opencolorio/gpu_shader_display_transform_vertex.glsl */
in vec2 texCoord;
in vec2 pos;
out vec2 texCoord_interp;
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f);
gl_Position.z = 1.0f;
texCoord_interp = texCoord;
}'''
fragment_shader = '''
in vec2 texCoord_interp;
out vec4 fragColor;
uniform sampler2D image;
uniform float exposure;
void main()
{
fragColor = texture(image, texCoord_interp) * vec4(exposure, exposure, exposure, 1.0f);
}'''
# shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
def draw_callback_px(self, context): def draw_callback_px(self, context):
@ -49,9 +23,6 @@ def draw_callback_px(self, context):
if self.area != context.area: if self.area != context.area:
return return
if image.gl_load():
raise Exception()
bottom = 0 bottom = 0
top = context.area.height top = context.area.height
right = context.area.width right = context.area.width
@ -59,39 +30,36 @@ def draw_callback_px(self, context):
position = Vector((right, top)) / 2 + self.offset position = Vector((right, top)) / 2 + self.offset
scale = Vector((context.area.width, context.area.width / 2)) * self.scale scale = Vector((context.area.width, context.area.width / 2)) * self.scale
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
coords = ((-0.5, -0.5), (0.5, -0.5), (0.5, 0.5), (-0.5, 0.5)) coords = ((-0.5, -0.5), (0.5, -0.5), (0.5, 0.5), (-0.5, 0.5))
uv_coords = ((0, 0), (1, 0), (1, 1), (0, 1)) uv_coords = ((0, 0), (1, 0), (1, 1), (0, 1))
batch = batch_for_shader(shader, 'TRI_FAN', batch = batch_for_shader(image_shader, 'TRI_FAN',
{"pos": coords, "texCoord": uv_coords}) {"pos": coords, "texCoord": uv_coords})
with gpu.matrix.push_pop(): with gpu.matrix.push_pop():
gpu.matrix.translate(position) gpu.matrix.translate(position)
gpu.matrix.scale(scale) gpu.matrix.scale(scale)
shader.bind() image_shader.bind()
shader.uniform_sampler("image", texture) image_shader.uniform_sampler("image", texture)
shader.uniform_float("exposure", self.exposure) image_shader.uniform_float("color", (self.exposure, self.exposure, self.exposure, 1.0))
batch.draw(shader) batch.draw(image_shader)
# Crosshair # Crosshair
# vertical # vertical
coords = ((self.mouse_position[0], bottom), (self.mouse_position[0], top)) coords = ((self.mouse_position[0], bottom), (self.mouse_position[0], top))
colors = ((1,) * 4,) * 2 colors = ((1,) * 4,) * 2
shader = gpu.shader.from_builtin('2D_FLAT_COLOR') batch = batch_for_shader(line_shader, 'LINES',
batch = batch_for_shader(shader, 'LINES',
{"pos": coords, "color": colors}) {"pos": coords, "color": colors})
shader.bind() line_shader.bind()
batch.draw(shader) batch.draw(line_shader)
# horizontal # horizontal
if bottom <= self.mouse_position[1] <= top: if bottom <= self.mouse_position[1] <= top:
coords = ((0, self.mouse_position[1]), (context.area.width, self.mouse_position[1])) coords = ((0, self.mouse_position[1]), (context.area.width, self.mouse_position[1]))
batch = batch_for_shader(shader, 'LINES', batch = batch_for_shader(line_shader, 'LINES',
{"pos": coords, "color": colors}) {"pos": coords, "color": colors})
shader.bind() line_shader.bind()
batch.draw(shader) batch.draw(line_shader)
class SUNPOS_OT_ShowHdr(bpy.types.Operator): class SUNPOS_OT_ShowHdr(bpy.types.Operator):

View File

@ -311,7 +311,7 @@ class SunPosAddonPreferences(AddonPreferences):
box = layout.box() box = layout.box()
col = box.column() col = box.column()
col.label(text="Show options or labels:") col.label(text="Show options and info:")
flow = col.grid_flow(columns=0, even_columns=True, even_rows=False, align=False) flow = col.grid_flow(columns=0, even_columns=True, even_rows=False, align=False)
flow.prop(self, "show_refraction") flow.prop(self, "show_refraction")
flow.prop(self, "show_overlays") flow.prop(self, "show_overlays")

View File

@ -432,10 +432,10 @@ translations_tuple = (
("fr_FR", "Projection inconnue", ("fr_FR", "Projection inconnue",
(False, ())), (False, ())),
), ),
(("*", "Show options or labels:"), (("*", "Show options and info:"),
(("scripts/addons/sun_position/properties.py:297",), (("scripts/addons/sun_position/properties.py:297",),
()), ()),
("fr_FR", "Afficher les options et étiquettes :", ("fr_FR", "Afficher les options et infos :",
(False, ())), (False, ())),
), ),
(("*", "ERROR: Could not parse coordinates"), (("*", "ERROR: Could not parse coordinates"),