[Bf-extensions-cvs] [48b9a4b2] master: archipack: bugfix thtottle update modal exit, performance improvement, draw windows and doors over wall
Stephen Leger
noreply at git.blender.org
Mon Jun 5 03:22:08 CEST 2017
Commit: 48b9a4b2e701612249bb622f60b979d1b1fad5ac
Author: Stephen Leger
Date: Mon Jun 5 03:21:54 2017 +0200
Branches: master
https://developer.blender.org/rBAC48b9a4b2e701612249bb622f60b979d1b1fad5ac
archipack: bugfix thtottle update modal exit, performance improvement, draw windows and doors over wall
===================================================================
M archipack/__init__.py
M archipack/archipack_autoboolean.py
M archipack/archipack_door.py
M archipack/archipack_manipulator.py
M archipack/archipack_snap.py
M archipack/archipack_wall2.py
M archipack/archipack_window.py
===================================================================
diff --git a/archipack/__init__.py b/archipack/__init__.py
index 6a28d816..371bbd94 100644
--- a/archipack/__init__.py
+++ b/archipack/__init__.py
@@ -258,7 +258,7 @@ class Archipack_Pref(AddonPreferences):
col.label(text="Manipulators:")
col.prop(self, "arrow_size")
col.prop(self, "handle_size")
-
+
# ----------------------------------------------------
# Archipack panels
@@ -418,12 +418,22 @@ class TOOLS_PT_Archipack_Create(Panel):
box = row.box()
box.label("Objects")
row = box.row(align=True)
- row.operator("archipack.window",
+ col = row.column()
+ subrow = col.row(align=True)
+ subrow.operator("archipack.window",
icon_value=icons_coll["window"].icon_id
).mode = 'CREATE'
- row.operator("archipack.door",
+ subrow.operator("archipack.window_draw",
+ text="",
+ icon='GREASEPENCIL')
+ col = row.column()
+ subrow = col.row(align=True)
+ subrow.operator("archipack.door",
icon_value=icons_coll["door"].icon_id
).mode = 'CREATE'
+ subrow.operator("archipack.door_draw",
+ text="",
+ icon='GREASEPENCIL')
row = box.row(align=True)
row.operator("archipack.stair",
icon_value=icons_coll["stair"].icon_id
diff --git a/archipack/archipack_autoboolean.py b/archipack/archipack_autoboolean.py
index ef9b2770..51da4150 100644
--- a/archipack/archipack_autoboolean.py
+++ b/archipack/archipack_autoboolean.py
@@ -30,6 +30,103 @@ from bpy.props import BoolProperty
from mathutils import Vector
+class ARCHIPACK_OT_single_boolean(Operator):
+ bl_idname = "archipack.single_boolean"
+ bl_label = "SingleBoolean"
+ bl_description = "Add single boolean for doors and windows"
+ bl_category = 'Archipack'
+ bl_options = {'REGISTER', 'UNDO'}
+ """
+ Wall must be active object
+ window or door must be selected
+ """
+
+ @classmethod
+ def poll(cls, context):
+ w = context.active_object
+ return (w.data is not None and
+ "archipack_wall2" in w.data and
+ len(context.selected_objects) == 2
+ )
+
+ # -----------------------------------------------------
+ # Draw (create UI interface)
+ # -----------------------------------------------------
+ def draw(self, context):
+ pass
+
+ def autoboolean(self, context, wall, o):
+ # generate holes for crossing window and doors
+ hole = self._generate_hole(context, o)
+ if hole is None:
+ return
+ # update / remove / add boolean modifier
+ modif = wall.modifiers.new('AutoBoolean', 'BOOLEAN')
+ modif.operation = 'DIFFERENCE'
+ modif.object = hole
+ # parenting childs to wall reference point
+ if wall.parent is None:
+ x, y, z = wall.bound_box[0]
+ context.scene.cursor_location = wall.matrix_world * Vector((x, y, z))
+ # fix issue #9
+ context.scene.objects.active = wall
+ bpy.ops.archipack.reference_point()
+ else:
+ context.scene.objects.active = wall.parent
+ bpy.ops.object.select_all(action='DESELECT')
+ wall.select = True
+ o.select = True
+ bpy.ops.archipack.parent_to_reference()
+
+ def _prepare_hole(self, hole):
+ hole.lock_location = (True, True, True)
+ hole.lock_rotation = (True, True, True)
+ hole.lock_scale = (True, True, True)
+ hole.draw_type = 'WIRE'
+ hole.hide_render = True
+ hole.hide_select = True
+ hole.select = True
+ hole.cycles_visibility.camera = False
+ hole.cycles_visibility.diffuse = False
+ hole.cycles_visibility.glossy = False
+ hole.cycles_visibility.shadow = False
+ hole.cycles_visibility.scatter = False
+ hole.cycles_visibility.transmission = False
+
+ def _generate_hole(self, context, o):
+ hole = None
+ # generate holes from archipack primitives
+ if o.data is not None:
+ # Keep separate as contains rules may vary from window to doors
+ if 'archipack_window' in o.data:
+ hole = o.data.archipack_window[0].interactive_hole(context, o)
+ elif 'archipack_door' in o.data:
+ hole = o.data.archipack_door[0].interactive_hole(context, o)
+
+ # Select all holes here, fix issue #13
+ if hole is not None:
+ self._prepare_hole(hole)
+ return hole
+
+ # -----------------------------------------------------
+ # Execute
+ # -----------------------------------------------------
+ def execute(self, context):
+ if context.mode == "OBJECT":
+ wall = context.scene.objects.active
+ for o in context.selected_objects:
+ if o != wall:
+ self.autoboolean(context, wall, o)
+ break
+ o.select = False
+ wall.select = True
+ context.scene.objects.active = wall
+ return {'FINISHED'}
+ else:
+ self.report({'WARNING'}, "Archipack: Option only valid in Object mode")
+ return {'CANCELLED'}
+
+
class ARCHIPACK_OT_auto_boolean(Operator):
bl_idname = "archipack.auto_boolean"
bl_label = "AutoBoolean"
@@ -274,8 +371,10 @@ class ARCHIPACK_OT_auto_boolean(Operator):
def register():
+ bpy.utils.register_class(ARCHIPACK_OT_single_boolean)
bpy.utils.register_class(ARCHIPACK_OT_auto_boolean)
def unregister():
+ bpy.utils.unregister_class(ARCHIPACK_OT_single_boolean)
bpy.utils.unregister_class(ARCHIPACK_OT_auto_boolean)
diff --git a/archipack/archipack_door.py b/archipack/archipack_door.py
index 061a100c..0456e148 100644
--- a/archipack/archipack_door.py
+++ b/archipack/archipack_door.py
@@ -33,7 +33,7 @@ from bpy.props import (
FloatProperty, IntProperty, CollectionProperty,
EnumProperty, BoolProperty, StringProperty
)
-from mathutils import Vector
+from mathutils import Vector, Matrix
# door component objects (panels, handles ..)
from .bmesh_utils import BmeshEdit as bmed
from .panel import Panel as DoorPanel
@@ -41,6 +41,8 @@ from .materialutils import MaterialUtils
from .archipack_handle import create_handle, door_handle_horizontal_01
from .archipack_manipulator import Manipulable
from .archipack_preset import ArchipackPreset
+from .archipack_gl import FeedbackPanel
+from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_origin_3d
SPACING = 0.005
BATTUE = 0.01
@@ -1697,6 +1699,105 @@ class ARCHIPACK_OT_door(Operator):
self.report({'WARNING'}, "Archipack: Option only valid in Object mode")
return {'CANCELLED'}
+
+class ARCHIPACK_OT_door_draw(Operator):
+ bl_idname = "archipack.door_draw"
+ bl_label = "Draw Doors"
+ bl_description = "Draw Doors over walls"
+ bl_category = 'Archipack'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ feedback = None
+
+ def mouse_to_matrix(self, context, event):
+ """
+ convert mouse pos to 3d point over plane defined by origin and normal
+ """
+ region = context.region
+ rv3d = context.region_data
+ co2d = (event.mouse_region_x, event.mouse_region_y)
+ view_vector_mouse = region_2d_to_vector_3d(region, rv3d, co2d)
+ ray_origin_mouse = region_2d_to_origin_3d(region, rv3d, co2d)
+ res, pt, y, i, o, tM = context.scene.ray_cast(
+ ray_origin_mouse,
+ view_vector_mouse)
+ if res and 'archipack_wall2' in o.data:
+ z = Vector((0, 0, 1))
+ d = o.data.archipack_wall2[0]
+ y = -y
+ pt += (0.5 * d.width) * y.normalized()
+ x = y.cross(z)
+ return True, Matrix([
+ [x.x, y.x, z.x, pt.x],
+ [x.y, y.y, z.y, pt.y],
+ [x.z, y.z, z.z, o.matrix_world.translation.z],
+ [0, 0, 0, 1]
+ ]), o
+ return False, Matrix(), None
+
+ @classmethod
+ def poll(cls, context):
+ return True
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row.label("Use Properties panel (N) to define parms", icon='INFO')
+
+ def draw_callback(self, _self, context):
+ self.feedback.draw(context)
+
+ def modal(self, context, event):
+
+ context.area.tag_redraw()
+ # print("modal event %s %s" % (event.type, event.value))
+ # if event.type == 'NONE':
+ # return {'PASS_THROUGH'}
+ res, tM, wall = self.mouse_to_matrix(context, event)
+ w = context.active_object
+ if res and ARCHIPACK_PT_door.filter(w):
+ w.matrix_world = tM
+
+ if event.value == 'PRESS':
+ if event.type in {'LEFTMOUSE', 'MOUSEMOVE'}:
+ if wall is not None:
+ context.scene.objects.active = wall
+ wall.select = True
+ bpy.ops.archipack.single_boolean()
+ wall.select = False
+ bpy.ops.archipack.door(auto_manipulate=False)
+ context.active_object.matrix_world = tM
+
+ if event.value == 'RELEASE':
+
+ if event.type in {'ESC', 'RIGHTMOUSE'}:
+ bpy.ops.archipack.door(mode='DELETE')
+ self.feedback.disable()
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ return {'FINISHED'}
+
+ return {'PASS_THROUGH'}
+
+ def invoke(self, context, event):
+
+ if context.mode == "OBJECT":
+ bpy.ops.archipack.door(auto_manipulate=False)
+ self.feedback = FeedbackPanel()
+ self.feedback.instructions(context, "Draw a door", "Click & Drag over a wall", [
+ ('LEFTCLICK', 'Create a door'),
+ ('RIGHTCLICK or ESC', 'exit')
+ ])
+ self.feedback.enable()
+ args = (self, context)
+
+ self._handle = bpy.types.SpaceView3D.d
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list