[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