Newer
Older
# SPDX-License-Identifier: GPL-2.0-or-later
# ----------------------------------------------------------
# File: measureit_main.py
# Main panel for different Measureit general actions
# Author: Antonio Vazquez (antonioya)
#
# ----------------------------------------------------------
# noinspection PyUnresolvedReferences
import bpy
# noinspection PyUnresolvedReferences
from bpy.types import PropertyGroup, Panel, Object, Operator, SpaceView3D
from bpy.props import IntProperty, CollectionProperty, FloatVectorProperty, BoolProperty, StringProperty, \
FloatProperty, EnumProperty
from bpy.app.handlers import persistent
# noinspection PyUnresolvedReferences
from .measureit_geometry import *
from .measureit_render import *
# ------------------------------------------------------
# Handler to detect new Blend load
#
# ------------------------------------------------------
# noinspection PyUnusedLocal
@persistent
def load_handler(dummy):
MEASUREIT_OT_RunHintDisplay.handle_remove(None, bpy.context)
# ------------------------------------------------------
# Handler to detect save Blend
# Clear not used measured
#
# ------------------------------------------------------
# noinspection PyUnusedLocal
@persistent
def save_handler(dummy):
# noinspection PyBroadException
try:
print("MeasureIt: Cleaning data")
objlist = bpy.context.scene.objects
for myobj in objlist:
if 'MeasureGenerator' in myobj:
mp = myobj.MeasureGenerator[0]
x = 0
for ms in mp.measureit_segments:
ms.name = "segment_" + str(x)
x += 1
if ms.glfree is True:
idx = mp.measureit_segments.find(ms.name)
if idx > -1:
print("MeasureIt: Removed segment not used")
mp.measureit_segments.remove(idx)
# reset size
mp.measureit_num = len(mp.measureit_segments)
except:
pass
bpy.app.handlers.load_post.append(load_handler)
bpy.app.handlers.save_pre.append(save_handler)
# ------------------------------------------------------------------
# Define property group class for measureit faces index
# ------------------------------------------------------------------
class MeasureitIndex(PropertyGroup):
glidx: IntProperty(name="index", description="vertex index")
# Register
bpy.utils.register_class(MeasureitIndex)
# ------------------------------------------------------------------
# Define property group class for measureit faces
# ------------------------------------------------------------------
class MeasureitFaces(PropertyGroup):
glface: IntProperty(name="glface", description="Face number")
# Array of index
measureit_index: CollectionProperty(type=MeasureitIndex)
# Register
bpy.utils.register_class(MeasureitFaces)
# ------------------------------------------------------------------
# Define property group class for measureit data
# ------------------------------------------------------------------
class MeasureitProperties(PropertyGroup):
gltype: IntProperty(name="gltype",
description="Measure type (1-Segment, 2-Label, etc..)", default=1)
glpointa: IntProperty(name="glpointa",
description="Hidden property for opengl")
glpointb: IntProperty(name="glpointb",
description="Hidden property for opengl")
glpointc: IntProperty(name="glpointc",
description="Hidden property for opengl")
glcolor: FloatVectorProperty(name="glcolor",
description="Color for the measure",
default=(0.173, 0.545, 1.0, 1.0),
min=0.1,
max=1,
subtype='COLOR',
size=4)
glview: BoolProperty(name="glview",
description="Measure visible/hide",
default=True)
glspace: FloatProperty(name='glspace', min=-100, max=100, default=0.1,
precision=3,
description='Distance to display measure')
glwidth: IntProperty(name='glwidth', min=1, max=10, default=1,
glfree: BoolProperty(name="glfree",
description="This measure is free and can be deleted",
default=False)
gltxt: StringProperty(name="gltxt", maxlen=256,
description="Short description (use | for line break)")
gladvance: BoolProperty(name="gladvance",
description="Advanced options as line width or position",
default=False)
gldefault: BoolProperty(name="gldefault",
description="Display measure in position calculated by default",
default=True)
glnormalx: FloatProperty(name="glnormalx",
description="Change orientation in X axis",
default=1, min=-1, max=1, precision=2)
glnormaly: FloatProperty(name="glnormaly",
description="Change orientation in Y axis",
default=0, min=-1, max=1, precision=2)
glnormalz: FloatProperty(name="glnormalz",
description="Change orientation in Z axis",
default=0, min=-1, max=1, precision=2)
glfont_size: IntProperty(name="Text Size",
description="Text size",
default=14, min=6, max=150)
glfont_align: EnumProperty(items=(('L', "Left Align", ""),
('C', "Center Align", ""),
('R', "Right Align", "")),
name="Align Font",
description="Set Font Alignment")
glfont_rotat: IntProperty(name='Rotate', min=0, max=360, default=0,
description="Text rotation in degrees")
gllink: StringProperty(name="gllink",
glocwarning: BoolProperty(name="glocwarning",
description="Display a warning if some axis is not used in distance",
default=True)
glocx: BoolProperty(name="glocx",
description="Include changes in X axis for calculating the distance",
default=True)
glocy: BoolProperty(name="glocy",
description="Include changes in Y axis for calculating the distance",
default=True)
glocz: BoolProperty(name="glocz",
description="Include changes in Z axis for calculating the distance",
default=True)
glfontx: IntProperty(name="glfontx",
description="Change font position in X axis",
default=0, min=-3000, max=3000)
glfonty: IntProperty(name="glfonty",
description="Change font position in Y axis",
default=0, min=-3000, max=3000)
gldist: BoolProperty(name="gldist",
description="Display distance for this measure",
default=True)
glnames: BoolProperty(name="glnames",
description="Display text for this measure",
default=True)
gltot: EnumProperty(items=(('99', "-", "Select a group for sum"),
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
('0', "A", ""),
('1', "B", ""),
('2', "C", ""),
('3', "D", ""),
('4', "E", ""),
('5', "F", ""),
('6', "G", ""),
('7', "H", ""),
('8', "I", ""),
('9', "J", ""),
('10', "K", ""),
('11', "L", ""),
('12', "M", ""),
('13', "N", ""),
('14', "O", ""),
('15', "P", ""),
('16', "Q", ""),
('17', "R", ""),
('18', "S", ""),
('19', "T", ""),
('20', "U", ""),
('21', "V", ""),
('22', "W", ""),
('23', "X", ""),
('24', "Y", ""),
('25', "Z", "")),
name="Sum in Group",
description="Add segment length in selected group")
glorto: EnumProperty(items=(('99', "None", ""),
('0', "A", "Point A must use selected point B location"),
('1', "B", "Point B must use selected point A location")),
name="Orthogonal",
description="Display point selected as orthogonal (select axis to copy)")
glorto_x: BoolProperty(name="ox",
glorto_y: BoolProperty(name="oy",
glorto_z: BoolProperty(name="oz",
glarrow_a: EnumProperty(items=(('99', "--", "No arrow"),
('1', "Line", "The point of the arrow are lines"),
('2', "Triangle", "The point of the arrow is triangle"),
('3', "TShape", "The point of the arrow is a T")),
name="A end",
description="Add arrows to point A")
glarrow_b: EnumProperty(items=(('99', "--", "No arrow"),
('1', "Line", "The point of the arrow are lines"),
('2', "Triangle", "The point of the arrow is triangle"),
('3', "TShape", "The point of the arrow is a T")),
name="B end",
description="Add arrows to point B")
glarrow_s: IntProperty(name="Size",
description="Arrow size",
default=15, min=6, max=500)
glarc_full: BoolProperty(name="arcfull",
glarc_extrad: BoolProperty(name="arcextrad",
description="Adapt radio length to arc line",
glarc_rad: BoolProperty(name="arc rad",
glarc_len: BoolProperty(name="arc len",
glarc_ang: BoolProperty(name="arc ang",
glarc_a: EnumProperty(items=(('99', "--", "No arrow"),
('1', "Line", "The point of the arrow are lines"),
('2', "Triangle", "The point of the arrow is triangle"),
('3', "TShape", "The point of the arrow is a T")),
name="Ar end",
description="Add arrows to point A")
glarc_b: EnumProperty(items=(('99', "--", "No arrow"),
('1', "Line", "The point of the arrow are lines"),
('2', "Triangle", "The point of the arrow is triangle"),
('3', "TShape", "The point of the arrow is a T")),
name="Br end",
description="Add arrows to point B")
glarc_s: IntProperty(name="Size",
description="Arrow size",
default=15, min=6, max=500)
glarc_txradio: StringProperty(name="txradio",
glarc_txlen: StringProperty(name="txlen",
glarc_txang: StringProperty(name="txang",
glcolorarea: FloatVectorProperty(name="glcolorarea",
description="Color for the measure of area",
default=(0.1, 0.1, 0.1, 1.0),
min=0.1,
max=1,
subtype='COLOR',
size=4)
# Array of faces
measureit_faces: CollectionProperty(type=MeasureitFaces)
# Register
bpy.utils.register_class(MeasureitProperties)
# ------------------------------------------------------------------
# Define object class (container of segments)
# Measureit
# ------------------------------------------------------------------
class MeasureContainer(PropertyGroup):
measureit_num: IntProperty(name='Number of measures', min=0, max=1000, default=0,
# Array of segments
measureit_segments: CollectionProperty(type=MeasureitProperties)
bpy.utils.register_class(MeasureContainer)
Object.MeasureGenerator = CollectionProperty(type=MeasureContainer)
# ------------------------------------------------------------------
# Define UI class
# Measureit
# ------------------------------------------------------------------
class MEASUREIT_PT_Edit(Panel):
bl_idname = "MEASUREIT_PT_Edit"
bl_label = "Items"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_parent_id = 'MEASUREIT_PT_Main'
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# -----------------------------------------------------
# Verify if visible
# -----------------------------------------------------
@classmethod
def poll(cls, context):
o = context.object
if o is None:
return False
if 'MeasureGenerator' not in o:
return False
else:
mp = context.object.MeasureGenerator[0]
if mp.measureit_num > 0:
return True
else:
return False
# -----------------------------------------------------
# Draw (create UI interface)
# -----------------------------------------------------
# noinspection PyUnusedLocal
def draw(self, context):
layout = self.layout
scene = context.scene
if context.object is not None:
if 'MeasureGenerator' in context.object:
box = layout.box()
row = box.row()
row.label(text=context.object.name)
row = box.row()
row.prop(scene, 'measureit_gl_precision', text="Precision")
row.prop(scene, 'measureit_units')
row = box.row()
row.prop(scene, 'measureit_gl_show_d', text="Distances", toggle=True, icon="ALIGN_CENTER")
row.prop(scene, 'measureit_gl_show_n', text="Texts", toggle=True, icon="FONT_DATA")
row = box.row()
row.prop(scene, 'measureit_hide_units', text="Hide measurement unit")
# Scale factor
row = box.row()
row.prop(scene, 'measureit_scale', text="Scale")
if scene.measureit_scale is True:
split = row.split(factor=0.25, align=False)
split.prop(scene, 'measureit_scale_color', text="")
split.prop(scene, 'measureit_scale_factor', text="1")
row = box.row()
row.separator()
row.prop(scene, 'measureit_gl_scaletxt', text="")
row.prop(scene, 'measureit_scale_font')
row.prop(scene, 'measureit_scale_precision', text="")
row = box.row()
row.prop(scene, 'measureit_scale_pos_x')
row.prop(scene, 'measureit_scale_pos_y')
# Override
row = box.row()
row.prop(scene, 'measureit_ovr', text="Override")
if scene.measureit_ovr is True:
split = row.split(factor=0.25, align=False)
split.prop(scene, 'measureit_ovr_color', text="")
split.prop(scene, 'measureit_ovr_width', text="Width")
row = box.row()
row.separator()
row.prop(scene, 'measureit_ovr_font', text="Font")
row.prop(scene, 'measureit_ovr_font_align', text="")
if scene.measureit_ovr_font_align == 'L':
row.prop(scene, 'measureit_ovr_font_rotation', text="Rotate")
mp = context.object.MeasureGenerator[0]
# -----------------
# loop
# -----------------
if mp.measureit_num > 0:
box = layout.box()
row = box.row(align=True)
row.operator("measureit.expandallsegment", text="Expand all", icon="ZOOM_IN")
row.operator("measureit.collapseallsegment", text="Collapse all", icon="ZOOM_OUT")
if mp.measureit_segments[idx].glfree is False:
add_item(box, idx, mp.measureit_segments[idx])
row = box.row()
row.operator("measureit.deleteallsegment", text="Delete all", icon="X")
# -----------------
# Sum loop segments
# -----------------
if mp.measureit_num > 0:
scale = bpy.context.scene.unit_settings.scale_length
tx = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
"T", "U", "V", "W", "X", "Y", "Z"]
tot = [0.0] * len(tx)
ac = [False] * len(tx)
myobj = context.object
obverts = get_mesh_vertices(myobj)
viewtot = False
ms = mp.measureit_segments[idx]
if (ms.gltype == 1 or ms.gltype == 12
or ms.gltype == 13 or ms.gltype == 14) and ms.gltot != '99' \
and ms.glfree is False: # only segments
if bpy.context.mode == "EDIT_MESH":
bm = bmesh.from_edit_mesh(bpy.context.edit_object.data)
if hasattr(bm.verts, "ensure_lookup_table"):
bm.verts.ensure_lookup_table()
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
if ms.glpointa <= len(obverts) and ms.glpointb <= len(obverts):
p1 = get_point(obverts[ms.glpointa].co, myobj)
if ms.gltype == 1:
p2 = get_point(obverts[ms.glpointb].co, myobj)
elif ms.gltype == 12:
p2 = get_point((0.0,
obverts[ms.glpointa].co[1],
obverts[ms.glpointa].co[2]), myobj)
elif ms.gltype == 13:
p2 = get_point((obverts[ms.glpointa].co[0],
0.0,
obverts[ms.glpointa].co[2]), myobj)
else:
p2 = get_point((obverts[ms.glpointa].co[0],
obverts[ms.glpointa].co[1],
0.0), myobj)
dist, distloc = distance(p1, p2, ms.glocx, ms.glocy, ms.glocz)
if dist == distloc:
usedist = dist
else:
usedist = distloc
usedist *= scale
tot[int(ms.gltot)] += usedist
ac[int(ms.gltot)] = True
viewtot = True
# -----------------
# Print values
# -----------------
if viewtot is True:
pr = scene.measureit_gl_precision
fmt = "%1." + str(pr) + "f"
units = scene.measureit_units
box = layout.box()
box.label(text="Totals", icon='SOLO_ON')
final = 0
if ac[idx] is True:
final += tot[idx]
tx_dist = format_distance(fmt, units, tot[idx])
row = box.row(align=True)
row.label(text="Group " + tx[idx] + ":")
row.label(text=" ")
row.label(text=tx_dist)
# Grand total
row = box.row(align=True)
row.label(text="")
row.label(text=" ")
row.label(text="-" * 20)
tx_dist = format_distance(fmt, units, final)
row = box.row(align=True)
row.label(text="")
row.label(text=" ")
row.label(text=tx_dist)
# delete all
row = box.row()
row.operator("measureit.deleteallsum", text="Delete all", icon="X")
# -----------------------------------------------------
# Add segment options to the panel.
# -----------------------------------------------------
def add_item(box, idx, segment):
if segment.glview is True:
row.prop(segment, 'glview', text="", toggle=True, icon=icon)
row.prop(segment, 'gladvance', text="", toggle=True, icon="PREFERENCES")
if segment.gltype == 20: # Area special
split = row.split(factor=0.15, align=True)
split.prop(segment, 'glcolorarea', text="")
split = split.split(factor=0.20, align=True)
split.prop(segment, 'glcolor', text="")
else:
split = row.split(factor=0.25, align=True)
split.prop(segment, 'glcolor', text="")
split.prop(segment, 'gltxt', text="")
op = row.operator("measureit.deletesegment", text="", icon="X")
op.tag = idx # saves internal data
if segment.gladvance is True:
row.prop(segment, 'glfont_size', text="Font")
row.prop(segment, 'glfont_align', text="")
if segment.glfont_align == 'L':
row.prop(segment, 'glfont_rotat', text="Rotate")
if segment.gltype != 9 and segment.gltype != 10 and segment.gltype != 20:
row.prop(segment, 'glspace', text="Distance")
row.prop(segment, 'glfontx', text="X")
row.prop(segment, 'glfonty', text="Y")
# Arrows
if segment.gltype != 9 and segment.gltype != 10 and segment.gltype != 20:
row.prop(segment, 'glarrow_a', text="")
row.prop(segment, 'glarrow_b', text="")
if segment.glarrow_a != '99' or segment.glarrow_b != '99':
row.prop(segment, 'glarrow_s', text="Size")
if segment.gltype != 2 and segment.gltype != 10:
if scene.measureit_gl_show_d is True and segment.gltype != 9:
row.prop(segment, 'gldist', text="Distance", toggle=True, icon="ALIGN_CENTER")
if scene.measureit_gl_show_n is True:
row.prop(segment, 'glnames', text="Text", toggle=True, icon="FONT_DATA")
# sum distances
if segment.gltype == 1 or segment.gltype == 12 or segment.gltype == 13 or segment.gltype == 14:
row.prop(segment, 'gltot', text="Sum")
if segment.gltype != 9 and segment.gltype != 10 and segment.gltype != 20:
row.prop(segment, 'glwidth', text="Line")
row.prop(segment, 'gldefault', text="Automatic position")
if segment.gldefault is False:
row.prop(segment, 'glnormalx', text="X")
row.prop(segment, 'glnormaly', text="Y")
row.prop(segment, 'glnormalz', text="Z")
# Loc axis
if segment.gltype != 2 and segment.gltype != 9 and segment.gltype != 10 \
and segment.gltype != 11 and segment.gltype != 12 and segment.gltype != 13 \
and segment.gltype != 14 and segment.gltype != 20:
row.prop(segment, 'glocx', text="X", toggle=True)
row.prop(segment, 'glocy', text="Y", toggle=True)
row.prop(segment, 'glocz', text="Z", toggle=True)
if segment.glocx is False or segment.glocy is False or segment.glocz is False:
row = box.row()
if segment.gltype == 1:
row.prop(segment, 'glorto', text="Orthogonal")
row.prop(segment, 'glocwarning', text="Warning")
if segment.gltype == 1:
if segment.glorto != "99":
row.prop(segment, 'glorto_x', text="X", toggle=True)
row.prop(segment, 'glorto_y', text="Y", toggle=True)
row.prop(segment, 'glorto_z', text="Z", toggle=True)
# Arc special
if segment.gltype == 11:
row.prop(segment, 'glarc_rad', text="Radius")
row.prop(segment, 'glarc_len', text="Length")
row.prop(segment, 'glarc_ang', text="Angle")
row.prop(segment, 'glarc_txradio', text="")
row.prop(segment, 'glarc_txlen', text="")
row.prop(segment, 'glarc_txang', text="")
row.prop(segment, 'glarc_full', text="Full Circle")
if segment.glarc_rad is True:
row.prop(segment, 'glarc_extrad', text="Adapt radio")
row.prop(segment, 'glarc_a', text="")
row.prop(segment, 'glarc_b', text="")
if segment.glarc_a != '99' or segment.glarc_b != '99':
row.prop(segment, 'glarc_s', text="Size")
# ------------------------------------------------------------------
# Define panel class for main functions.
# ------------------------------------------------------------------
class MEASUREIT_PT_Main(Panel):
bl_idname = "MEASUREIT_PT_Main"
bl_space_type = 'VIEW_3D'
bl_options = {'DEFAULT_CLOSED'}
# ------------------------------
# Draw UI
# ------------------------------
def draw(self, context):
layout = self.layout
scene = context.scene
# ------------------------------
# Tool Buttons
# ------------------------------
box = layout.box()
# ------------------------------
# Display Buttons
# ------------------------------
row = box.row()
if context.window_manager.measureit_run_opengl is False:
icon = 'PLAY'
txt = 'Show'
else:
icon = "PAUSE"
txt = 'Hide'
row.operator("measureit.runopengl", text=txt, icon=icon)
row.prop(scene, "measureit_gl_ghost", text="", icon='GHOST_ENABLED')
# Tools
box = layout.box()
box.label(text="Add Measures")
row.operator("measureit.addsegment", text="Segment")
row.prop(scene, "measureit_sum", text="Sum")
# To origin
row = box.row()
op = row.operator("measureit.addsegmentorto", text="X")
op.tag = 0 # saves internal data
op = row.operator("measureit.addsegmentorto", text="Y")
op.tag = 1 # saves internal data
op = row.operator("measureit.addsegmentorto", text="Z")
op.tag = 2 # saves internal data
row = box.row()
row.operator("measureit.addangle", text="Angle", icon="LINCURVE")
row.operator("measureit.addarc", text="Arc")
row = box.row()
row.operator("measureit.addlabel", text="Label", icon="FONT_DATA")
row.operator("measureit.addnote", text="Annotation")
row = box.row()
row.operator("measureit.addlink", text="Link")
row.operator("measureit.addorigin", text="Origin")
row = box.row()
row.operator("measureit.addarea", text="Area", icon="MESH_GRID")
# ------------------------------
# Debug data
# ------------------------------
box = layout.box()
if scene.measureit_debug is False:
row.prop(scene, "measureit_debug", icon="TRIA_RIGHT",
text="Mesh Debug", emboss=False)
else:
row.prop(scene, "measureit_debug", icon="TRIA_DOWN",
text="Mesh Debug", emboss=False)
row = box.row()
split = row.split(factor=0.10, align=True)
split.prop(scene, 'measureit_debug_obj_color', text="")
split.prop(scene, "measureit_debug_objects", icon="OBJECT_DATA")
split.prop(scene, "measureit_debug_object_loc", icon="EMPTY_DATA")
row = box.row()
split = row.split(factor=0.10, align=True)
split.prop(scene, 'measureit_debug_vert_color', text="")
split.prop(scene, "measureit_debug_vertices", icon="VERTEXSEL")
split.prop(scene, "measureit_debug_vert_loc", icon="EMPTY_DATA")
if scene.measureit_debug_vert_loc is True:
split.prop(scene, 'measureit_debug_vert_loc_toggle', text="")
row = box.row()
split = row.split(factor=0.10, align=True)
split.prop(scene, 'measureit_debug_edge_color', text="")
split = split.split(factor=0.5, align=True)
split.prop(scene, "measureit_debug_edges", icon="EDGESEL")
row = box.row()
split = row.split(factor=0.10, align=True)
split.prop(scene, 'measureit_debug_face_color', text="")
split = split.split(factor=0.5, align=True)
split.prop(scene, "measureit_debug_faces", icon="FACESEL")
row = box.row()
split = row.split(factor=0.10, align=True)
split.prop(scene, 'measureit_debug_norm_color', text="")
if scene.measureit_debug_normals is False:
split = split.split(factor=0.50, align=True)
split.prop(scene, "measureit_debug_normals", icon="OBJECT_ORIGIN")
split = split.split(factor=0.5, align=True)
split.prop(scene, "measureit_debug_normals", icon="OBJECT_ORIGIN")
split.prop(scene, "measureit_debug_normal_size")
row = box.row()
split = row.split(factor=0.10, align=True)
split.separator()
split.prop(scene, "measureit_debug_normal_details")
split.prop(scene, 'measureit_debug_width', text="Thickness")
row = box.row(align=True)
row.prop(scene, "measureit_debug_select", icon="GHOST_ENABLED")
row.prop(scene, 'measureit_debug_font', text="Font")
row.prop(scene, 'measureit_debug_precision', text="Precision")
# ------------------------------------------------------------------
# Define panel class for conf functions.
# ------------------------------------------------------------------
class MEASUREIT_PT_Conf(Panel):
bl_idname = "MEASUREIT_PT_Conf"
bl_space_type = 'VIEW_3D'
bl_parent_id = 'MEASUREIT_PT_Main'
bl_options = {'DEFAULT_CLOSED'}
# ------------------------------
# Draw UI
# ------------------------------
def draw(self, context):
layout = self.layout
scene = context.scene
# Configuration data
box = layout.box()
row = box.row()
split = row.split(factor=0.2, align=True)
split.label(text="Text")
split = split.split(factor=0.2, align=True)
split.prop(scene, "measureit_default_color", text="")
split.prop(scene, "measureit_gl_txt", text="")
row.prop(scene, "measureit_hint_space")
row.prop(scene, "measureit_font_align", text="")
# Arrow
row.prop(scene, "measureit_glarrow_a", text="")
row.prop(scene, "measureit_glarrow_b", text="")
if scene.measureit_glarrow_a != '99' or scene.measureit_glarrow_b != '99':
row.prop(scene, "measureit_glarrow_s", text="Size")
row.prop(scene, "measureit_font_size")
if scene.measureit_font_align == 'L':
row.prop(scene, "measureit_font_rotation", text="Rotate")
# ------------------------------------------------------------------
# Define panel class for render functions.
# ------------------------------------------------------------------
class MEASUREIT_PT_Render(Panel):
bl_idname = "MEASUREIT_PT_Render"
bl_space_type = 'VIEW_3D'
bl_category= 'Display'
bl_parent_id = 'MEASUREIT_PT_Main'
bl_options = {'DEFAULT_CLOSED'}
# ------------------------------
# Draw UI
# ------------------------------
def draw(self, context):
layout = self.layout
scene = context.scene
# Render settings
box = layout.box()
row = box.row()
row.prop(scene, "measureit_render_type")
row = box.row()
row.operator("measureit.rendersegment", icon='SCRIPT')
row = box.row()
row.prop(scene, "measureit_render", text="Save render image")
row = box.row()
row.prop(scene, "measureit_rf", text="Frame")
if scene.measureit_rf is True:
row.prop(scene, "measureit_rf_color", text="Color")
row = box.row()
row.prop(scene, "measureit_rf_border", text="Space")
row.prop(scene, "measureit_rf_line", text="Width")
# -------------------------------------------------------------
# Defines button that adds a measure segment
#
# -------------------------------------------------------------
class MEASUREIT_OT_AddSegment(Operator):
bl_idname = "measureit.addsegment"
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
bl_label = "Add"
bl_description = "(EDITMODE only) Add a new measure segment between 2 vertices (select 2 vertices or more)"
# ------------------------------
# Poll
# ------------------------------
@classmethod
def poll(cls, context):
o = context.object
if o is None:
return False
else:
if o.type == "MESH":
if bpy.context.mode == 'EDIT_MESH':
return True
else:
return False
else:
return False
# ------------------------------
# Execute button action
# ------------------------------
def execute(self, context):
if context.area.type == 'VIEW_3D':
# Add properties
scene = context.scene
mainobject = context.object
mylist = get_smart_selected(mainobject)
if len(mylist) < 2: # if not selected linked vertex
mylist = get_selected_vertex(mainobject)
if len(mylist) >= 2:
if 'MeasureGenerator' not in mainobject:
mainobject.MeasureGenerator.add()
mp = mainobject.MeasureGenerator[0]
for x in range(0, len(mylist) - 1, 2):
# -----------------------
# Only if not exist
# -----------------------
if exist_segment(mp, mylist[x], mylist[x + 1]) is False:
# Create all array elements
for cont in range(len(mp.measureit_segments) - 1, mp.measureit_num):
mp.measureit_segments.add()
# Set values
ms = mp.measureit_segments[mp.measureit_num]
ms.gltype = 1
ms.glpointa = mylist[x]
ms.glpointb = mylist[x + 1]
ms.glarrow_a = scene.measureit_glarrow_a
ms.glarrow_b = scene.measureit_glarrow_b
ms.glarrow_s = scene.measureit_glarrow_s
# color
ms.glcolor = scene.measureit_default_color
# dist
ms.glspace = scene.measureit_hint_space
# text
ms.gltxt = scene.measureit_gl_txt
ms.glfont_size = scene.measureit_font_size
ms.glfont_align = scene.measureit_font_align
ms.glfont_rotat = scene.measureit_font_rotation
# Sum group
ms.gltot = scene.measureit_sum
# Add index
mp.measureit_num += 1
# redraw
context.area.tag_redraw()
return {'FINISHED'}
else:
self.report({'ERROR'},
"MeasureIt: Select at least two vertices for creating measure segment.")
return {'FINISHED'}
else:
self.report({'WARNING'},
"View3D not found, cannot run operator")
return {'CANCELLED'}
# -------------------------------------------------------------
# Defines button that adds an area measure
#
# -------------------------------------------------------------
class MEASUREIT_OT_AddArea(Operator):
bl_idname = "measureit.addarea"
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
bl_label = "Area"
bl_description = "(EDITMODE only) Add a new measure for area (select 1 o more faces)"
# ------------------------------
# Poll
# ------------------------------
@classmethod
def poll(cls, context):
o = context.object
if o is None:
return False
else:
if o.type == "MESH":
if bpy.context.mode == 'EDIT_MESH':
return True
else:
return False
else:
return False
# ------------------------------
# Execute button action
# ------------------------------
def execute(self, context):
if context.area.type == 'VIEW_3D':
# Add properties
scene = context.scene
mainobject = context.object
mylist = get_selected_faces(mainobject)
if len(mylist) >= 1:
if 'MeasureGenerator' not in mainobject:
mainobject.MeasureGenerator.add()
mp = mainobject.MeasureGenerator[0]
mp.measureit_segments.add()
ms = mp.measureit_segments[mp.measureit_num]
ms.gltype = 20
f = -1
for face in mylist:
# Create array elements
ms.measureit_faces.add()
f += 1
# Set values
mf = ms.measureit_faces[f]
mf.glface = f
i = 0
for v in face:
mf.measureit_index.add()
mi = mf.measureit_index[i]
mi.glidx = v
i += 1
# color
rgb = scene.measureit_default_color
ms.glcolor = (rgb[0], rgb[1], rgb[2], 0.4)
# dist
ms.glspace = scene.measureit_hint_space
# text
ms.gltxt = scene.measureit_gl_txt
ms.glfont_size = scene.measureit_font_size
ms.glfont_align = scene.measureit_font_align
ms.glfont_rotat = scene.measureit_font_rotation
# Sum group
ms.gltot = scene.measureit_sum
# Add index
mp.measureit_num += 1
# redraw
context.area.tag_redraw()
return {'FINISHED'}
else:
self.report({'ERROR'},
"MeasureIt: Select at least one face for creating area measure. ")
return {'FINISHED'}
else:
self.report({'WARNING'},
"View3D not found, cannot run operator")
return {'CANCELLED'}
# -------------------------------------------------------------
# Defines button that adds a measure segment to x/y/z origin
#
# -------------------------------------------------------------
class MEASUREIT_OT_AddSegmentOrto(Operator):
bl_idname = "measureit.addsegmentorto"
bl_label = "Add"
bl_description = "(EDITMODE only) Add a new measure segment from vertex to object origin for one " \
"axis (select 1 vertex)"
# ------------------------------
# Poll
# ------------------------------
@classmethod
def poll(cls, context):
o = context.object
if o is None:
return False
else:
if o.type == "MESH":
if bpy.context.mode == 'EDIT_MESH':
return True
else:
return False
else:
return False
# ------------------------------
# Execute button action
# ------------------------------
def execute(self, context):
if context.area.type == 'VIEW_3D':