io_scene_3ds: Added unit measure convert option #104769
@ -55,6 +55,11 @@ class Import3DS(bpy.types.Operator, ImportHelper):
|
|||||||
soft_min=0.0, soft_max=1000.0,
|
soft_min=0.0, soft_max=1000.0,
|
||||||
default=10.0,
|
default=10.0,
|
||||||
)
|
)
|
||||||
|
convert_measure: BoolProperty(
|
||||||
|
name="Convert Measure",
|
||||||
|
description="Convert from millimeters to meters",
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
use_image_search: BoolProperty(
|
use_image_search: BoolProperty(
|
||||||
name="Image Search",
|
name="Image Search",
|
||||||
description="Search subdirectories for any associated images "
|
description="Search subdirectories for any associated images "
|
||||||
@ -112,7 +117,7 @@ class Export3DS(bpy.types.Operator, ExportHelper):
|
|||||||
min=0.0, max=100000.0,
|
min=0.0, max=100000.0,
|
||||||
soft_min=0.0, soft_max=100000.0,
|
soft_min=0.0, soft_max=100000.0,
|
||||||
default=1.0,
|
default=1.0,
|
||||||
)
|
)
|
||||||
use_selection: BoolProperty(
|
use_selection: BoolProperty(
|
||||||
name="Selection Only",
|
name="Selection Only",
|
||||||
description="Export selected objects only",
|
description="Export selected objects only",
|
||||||
|
@ -1209,7 +1209,7 @@ def make_track_chunk(ID, ob, ob_pos, ob_rot, ob_size):
|
|||||||
|
|
||||||
elif ID == ROT_TRACK_TAG: # Rotation (angle first [radians], followed by axis)
|
elif ID == ROT_TRACK_TAG: # Rotation (angle first [radians], followed by axis)
|
||||||
quat = ob_rot.to_quaternion().inverted()
|
quat = ob_rot.to_quaternion().inverted()
|
||||||
track_chunk.add_variable("rotation", _3ds_point_4d((quat.angle, quat.axis.x, quat.axis.y, quat.axis.z)))
|
track_chunk.add_variable("rotation", _3ds_point_4d((quat.angle, quat.axis,x, quat.axis.y, quat.axis.z)))
|
||||||
|
|
||||||
elif ID == SCL_TRACK_TAG: # Scale vector
|
elif ID == SCL_TRACK_TAG: # Scale vector
|
||||||
track_chunk.add_variable("scale", _3ds_point_3d(ob_size))
|
track_chunk.add_variable("scale", _3ds_point_3d(ob_size))
|
||||||
|
@ -325,7 +325,8 @@ def add_texture_to_material(image, contextWrapper, pct, extend, alpha, scale, of
|
|||||||
childs_list = []
|
childs_list = []
|
||||||
parent_list = []
|
parent_list = []
|
||||||
|
|
||||||
def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAIN, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE):
|
def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAIN,
|
||||||
|
IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE):
|
||||||
|
|
||||||
contextObName = None
|
contextObName = None
|
||||||
contextLamp = None
|
contextLamp = None
|
||||||
@ -362,15 +363,9 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
pivot_list = [] # pivots with hierarchy handling
|
pivot_list = [] # pivots with hierarchy handling
|
||||||
trackposition = {} # keep track to position for target calculation
|
trackposition = {} # keep track to position for target calculation
|
||||||
|
|
||||||
def putContextMesh(
|
def putContextMesh(context, myContextMesh_vertls, myContextMesh_facels, myContextMesh_flag,
|
||||||
context,
|
myContextMeshMaterials, myContextMesh_smooth, WORLD_MATRIX):
|
||||||
myContextMesh_vertls,
|
|
||||||
myContextMesh_facels,
|
|
||||||
myContextMesh_flag,
|
|
||||||
myContextMeshMaterials,
|
|
||||||
myContextMesh_smooth,
|
|
||||||
WORLD_MATRIX,
|
|
||||||
):
|
|
||||||
bmesh = bpy.data.meshes.new(contextObName)
|
bmesh = bpy.data.meshes.new(contextObName)
|
||||||
|
|
||||||
if myContextMesh_facels is None:
|
if myContextMesh_facels is None:
|
||||||
@ -431,8 +426,8 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
imported_objects.append(ob)
|
imported_objects.append(ob)
|
||||||
|
|
||||||
if myContextMesh_flag:
|
if myContextMesh_flag:
|
||||||
"""Bit 0 (0x1) sets edge CA visible, Bit 1 (0x2) sets edge BC visible and Bit 2 (0x4) sets edge AB visible
|
"""Bit 0 (0x1) sets edge CA visible, Bit 1 (0x2) sets edge BC visible and
|
||||||
In Blender we use sharp edges for those flags"""
|
Bit 2 (0x4) sets edge AB visible. In Blender we use sharp edges for those flags."""
|
||||||
for f, pl in enumerate(bmesh.polygons):
|
for f, pl in enumerate(bmesh.polygons):
|
||||||
face = myContextMesh_facels[f]
|
face = myContextMesh_facels[f]
|
||||||
faceflag = myContextMesh_flag[f]
|
faceflag = myContextMesh_flag[f]
|
||||||
@ -541,7 +536,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
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 colorchunks are present."""
|
||||||
tiling = read_short(temp_chunk)
|
tiling = read_short(temp_chunk)
|
||||||
if tiling & 0x1:
|
if tiling & 0x1:
|
||||||
extend = 'decal'
|
extend = 'decal'
|
||||||
@ -620,7 +615,7 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
|
|
||||||
def read_track_data(track_chunk):
|
def read_track_data(track_chunk):
|
||||||
"""Trackflags 0x1, 0x2 and 0x3 are for looping. 0x8, 0x10 and 0x20
|
"""Trackflags 0x1, 0x2 and 0x3 are for looping. 0x8, 0x10 and 0x20
|
||||||
locks the XYZ axes. 0x100, 0x200 and 0x400 unlinks the XYZ axes"""
|
locks the XYZ axes. 0x100, 0x200 and 0x400 unlinks the XYZ axes."""
|
||||||
tflags = read_short(track_chunk)
|
tflags = read_short(track_chunk)
|
||||||
contextTrack_flag = tflags
|
contextTrack_flag = tflags
|
||||||
temp_data = file.read(SZ_U_INT * 2)
|
temp_data = file.read(SZ_U_INT * 2)
|
||||||
@ -687,7 +682,8 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
|
|
||||||
# is it an object info chunk?
|
# is it an object info chunk?
|
||||||
elif new_chunk.ID == OBJECTINFO:
|
elif new_chunk.ID == OBJECTINFO:
|
||||||
process_next_chunk(context, file, new_chunk, imported_objects, CONSTRAIN, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE)
|
process_next_chunk(context, file, new_chunk, imported_objects, CONSTRAIN,
|
||||||
|
IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE)
|
||||||
|
|
||||||
# keep track of how much we read in the main chunk
|
# keep track of how much we read in the main chunk
|
||||||
new_chunk.bytes_read += temp_chunk.bytes_read
|
new_chunk.bytes_read += temp_chunk.bytes_read
|
||||||
@ -1105,6 +1101,8 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
for keydata in keyframe_data.items():
|
for keydata in keyframe_data.items():
|
||||||
trackposition[keydata[0]] = keydata[1] # Keep track to position for target calculation
|
trackposition[keydata[0]] = keydata[1] # Keep track to position for target calculation
|
||||||
child.location = apply_constrain(keydata[1]) if hierarchy == ROOT_OBJECT else mathutils.Vector(keydata[1])
|
child.location = apply_constrain(keydata[1]) if hierarchy == ROOT_OBJECT else mathutils.Vector(keydata[1])
|
||||||
|
if MEASURE:
|
||||||
|
child.location = child.location * 0.001
|
||||||
if hierarchy == ROOT_OBJECT:
|
if hierarchy == ROOT_OBJECT:
|
||||||
child.location.rotate(CONVERSE)
|
child.location.rotate(CONVERSE)
|
||||||
if not contextTrack_flag & 0x100: # Flag 0x100 unlinks X axis
|
if not contextTrack_flag & 0x100: # Flag 0x100 unlinks X axis
|
||||||
@ -1131,6 +1129,8 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
scale = mathutils.Vector.Fill(3, (CONSTRAIN * 0.1)) if CONSTRAIN != 0.0 else child.scale
|
scale = mathutils.Vector.Fill(3, (CONSTRAIN * 0.1)) if CONSTRAIN != 0.0 else child.scale
|
||||||
transformation = mathutils.Matrix.LocRotScale(locate, rotate, scale)
|
transformation = mathutils.Matrix.LocRotScale(locate, rotate, scale)
|
||||||
child.matrix_world = transformation
|
child.matrix_world = transformation
|
||||||
|
if MEASURE:
|
||||||
|
child.matrix_world = mathutils.Matrix.Scale(0.001,4) @ child.matrix_world
|
||||||
if hierarchy == ROOT_OBJECT:
|
if hierarchy == ROOT_OBJECT:
|
||||||
child.matrix_world = CONVERSE @ child.matrix_world
|
child.matrix_world = CONVERSE @ child.matrix_world
|
||||||
child.keyframe_insert(data_path="rotation_euler", index=0, frame=keydata[0])
|
child.keyframe_insert(data_path="rotation_euler", index=0, frame=keydata[0])
|
||||||
@ -1305,7 +1305,8 @@ def process_next_chunk(context, file, previous_chunk, imported_objects, CONSTRAI
|
|||||||
# IMPORT #
|
# IMPORT #
|
||||||
##########
|
##########
|
||||||
|
|
||||||
def load_3ds(filepath, context, CONSTRAIN=10.0, IMAGE_SEARCH=True, WORLD_MATRIX=False, KEYFRAME=True, APPLY_MATRIX=True, CONVERSE=None):
|
def load_3ds(filepath, context, CONSTRAIN=10.0, MEASURE=False, IMAGE_SEARCH=True,
|
||||||
|
WORLD_MATRIX=False, KEYFRAME=True, APPLY_MATRIX=True, CONVERSE=None):
|
||||||
|
|
||||||
print("importing 3DS: %r..." % (filepath), end="")
|
print("importing 3DS: %r..." % (filepath), end="")
|
||||||
|
|
||||||
@ -1335,7 +1336,8 @@ def load_3ds(filepath, context, CONSTRAIN=10.0, IMAGE_SEARCH=True, WORLD_MATRIX=
|
|||||||
scn = context.scene
|
scn = context.scene
|
||||||
|
|
||||||
imported_objects = [] # Fill this list with objects
|
imported_objects = [] # Fill this list with objects
|
||||||
process_next_chunk(context, file, current_chunk, imported_objects, CONSTRAIN, IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE)
|
process_next_chunk(context, file, current_chunk, imported_objects, CONSTRAIN,
|
||||||
|
IMAGE_SEARCH, WORLD_MATRIX, KEYFRAME, CONVERSE, MEASURE)
|
||||||
|
|
||||||
# fixme, make unglobal
|
# fixme, make unglobal
|
||||||
object_dictionary.clear()
|
object_dictionary.clear()
|
||||||
@ -1344,8 +1346,13 @@ def load_3ds(filepath, context, CONSTRAIN=10.0, IMAGE_SEARCH=True, WORLD_MATRIX=
|
|||||||
if APPLY_MATRIX:
|
if APPLY_MATRIX:
|
||||||
for ob in imported_objects:
|
for ob in imported_objects:
|
||||||
if ob.type == 'MESH':
|
if ob.type == 'MESH':
|
||||||
me = ob.data
|
ob.data.transform(ob.matrix_local.inverted())
|
||||||
me.transform(ob.matrix_local.inverted())
|
|
||||||
|
if MEASURE:
|
||||||
|
unit_mtx = mathutils.Matrix.Scale(0.001,4)
|
||||||
|
for ob in imported_objects:
|
||||||
|
if ob.type == 'MESH':
|
||||||
|
ob.data.transform(unit_mtx)
|
||||||
|
|
||||||
if CONVERSE and not KEYFRAME:
|
if CONVERSE and not KEYFRAME:
|
||||||
for ob in imported_objects:
|
for ob in imported_objects:
|
||||||
@ -1424,25 +1431,16 @@ def load_3ds(filepath, context, CONSTRAIN=10.0, IMAGE_SEARCH=True, WORLD_MATRIX=
|
|||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
def load(operator,
|
def load(operator, context, filepath="", constrain_size=0.0,
|
||||||
context,
|
convert_measure=False, use_image_search=True,
|
||||||
filepath="",
|
use_world_matrix=False, read_keyframe=True,
|
||||||
constrain_size=0.0,
|
use_apply_transform=True, global_matrix=None,
|
||||||
use_image_search=True,
|
|
||||||
use_world_matrix=False,
|
|
||||||
read_keyframe=True,
|
|
||||||
use_apply_transform=True,
|
|
||||||
global_matrix=None,
|
|
||||||
):
|
):
|
||||||
|
|
||||||
load_3ds(filepath,
|
load_3ds(filepath, context, CONSTRAIN=constrain_size,
|
||||||
context,
|
MEASURE=convert_measure, IMAGE_SEARCH=use_image_search,
|
||||||
CONSTRAIN=constrain_size,
|
WORLD_MATRIX=use_world_matrix, KEYFRAME=read_keyframe,
|
||||||
IMAGE_SEARCH=use_image_search,
|
APPLY_MATRIX=use_apply_transform, CONVERSE=global_matrix,
|
||||||
WORLD_MATRIX=use_world_matrix,
|
|
||||||
KEYFRAME=read_keyframe,
|
|
||||||
APPLY_MATRIX=use_apply_transform,
|
|
||||||
CONVERSE=global_matrix,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
Loading…
Reference in New Issue
Block a user