archipack: remove 2d to 3d module (shapely dep issue)

This commit is contained in:
stephen leger 2017-07-24 17:26:43 +02:00
parent 5bf39c3cfb
commit d1b57c76ad
5 changed files with 3 additions and 2848 deletions

View File

@ -27,14 +27,14 @@
bl_info = {
'name': 'Archipack',
'description': 'Architectural objects and 2d polygons detection from unordered splines',
'description': 'Architectural objects',
'author': 's-leger',
'license': 'GPL',
'deps': 'shapely',
'deps': '',
'version': (1, 2, 6),
'blender': (2, 7, 8),
'location': 'View3D > Tools > Create > Archipack',
'warning': '2d to 3d require shapely python module (see setup in documentation)',
'warning': '',
'wiki_url': 'https://github.com/s-leger/archipack/wiki',
'tracker_url': 'https://github.com/s-leger/archipack/issues',
'link': 'https://github.com/s-leger/archipack',
@ -53,19 +53,12 @@ if "bpy" in locals():
imp.reload(archipack_door)
imp.reload(archipack_window)
imp.reload(archipack_stair)
imp.reload(archipack_wall)
imp.reload(archipack_wall2)
imp.reload(archipack_slab)
imp.reload(archipack_fence)
imp.reload(archipack_truss)
imp.reload(archipack_floor)
imp.reload(archipack_rendering)
try:
imp.reload(archipack_polylib)
HAS_POLYLIB = True
except:
HAS_POLYLIB = False
pass
print("archipack: reload ready")
else:
@ -76,24 +69,12 @@ else:
from . import archipack_door
from . import archipack_window
from . import archipack_stair
from . import archipack_wall
from . import archipack_wall2
from . import archipack_slab
from . import archipack_fence
from . import archipack_truss
from . import archipack_floor
from . import archipack_rendering
try:
"""
polylib depends on shapely
raise ImportError when not meet
"""
from . import archipack_polylib
HAS_POLYLIB = True
except:
print("archipack: shapely not found, using built in modules only")
HAS_POLYLIB = False
pass
print("archipack: ready")
@ -121,14 +102,11 @@ icons_collection = {}
def update_panel(self, context):
try:
bpy.utils.unregister_class(TOOLS_PT_Archipack_PolyLib)
bpy.utils.unregister_class(TOOLS_PT_Archipack_Tools)
bpy.utils.unregister_class(TOOLS_PT_Archipack_Create)
except:
pass
prefs = context.user_preferences.addons[__name__].preferences
TOOLS_PT_Archipack_PolyLib.bl_category = prefs.tools_category
bpy.utils.register_class(TOOLS_PT_Archipack_PolyLib)
TOOLS_PT_Archipack_Tools.bl_category = prefs.tools_category
bpy.utils.register_class(TOOLS_PT_Archipack_Tools)
TOOLS_PT_Archipack_Create.bl_category = prefs.create_category
@ -155,11 +133,6 @@ class Archipack_Pref(AddonPreferences):
description="Put Achipack's object into a sub menu (shift+a)",
default=True
)
enable_2d_to_3d = BoolProperty(
name="Enable 2d to 3d",
description="Enable 2d to 3d module",
default=False
)
max_style_draw_tool = BoolProperty(
name="Draw a wall use 3dsmax style",
description="Reverse clic / release cycle for Draw a wall",
@ -251,12 +224,6 @@ class Archipack_Pref(AddonPreferences):
box.label("Features")
box.prop(self, "max_style_draw_tool")
box = layout.box()
box.label("2d to 3d")
if not HAS_POLYLIB:
box.label(text="WARNING Shapely python module not found", icon="ERROR")
box.label(text="2d to 3d tools are disabled, see setup in documentation")
box.prop(self, "enable_2d_to_3d")
box = layout.box()
row = box.row()
split = row.split(percentage=0.5)
col = split.column()
@ -286,114 +253,6 @@ class Archipack_Pref(AddonPreferences):
# ----------------------------------------------------
class TOOLS_PT_Archipack_PolyLib(Panel):
bl_label = "Archipack 2d to 3d"
bl_idname = "TOOLS_PT_Archipack_PolyLib"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = "Tools"
bl_context = "objectmode"
@classmethod
def poll(self, context):
global archipack_polylib
return (HAS_POLYLIB and
context.user_preferences.addons[__name__].preferences.enable_2d_to_3d and
((archipack_polylib.vars_dict['select_polygons'] is not None) or
(context.object is not None and context.object.type == 'CURVE')))
def draw(self, context):
global icons_collection
icons = icons_collection["main"]
layout = self.layout
row = layout.row(align=True)
box = row.box()
row = box.row(align=True)
row.operator(
"archipack.polylib_detect",
icon_value=icons["detect"].icon_id,
text='Detect'
).extend = context.window_manager.archipack_polylib.extend
row.prop(context.window_manager.archipack_polylib, "extend")
row = box.row(align=True)
row.prop(context.window_manager.archipack_polylib, "resolution")
row = box.row(align=True)
row.label(text="Polygons")
row = box.row(align=True)
row.operator(
"archipack.polylib_pick_2d_polygons",
icon_value=icons["selection"].icon_id,
text='Select'
).action = 'select'
row.operator(
"archipack.polylib_pick_2d_polygons",
icon_value=icons["union"].icon_id,
text='Union'
).action = 'union'
row.operator(
"archipack.polylib_output_polygons",
icon_value=icons["polygons"].icon_id,
text='All')
row = box.row(align=True)
row.operator(
"archipack.polylib_pick_2d_polygons",
text='Wall',
icon_value=icons["wall"].icon_id).action = 'wall'
row.prop(context.window_manager.archipack_polylib, "solidify_thickness")
row = box.row(align=True)
row.operator("archipack.polylib_pick_2d_polygons",
text='Window',
icon_value=icons["window"].icon_id).action = 'window'
row.operator("archipack.polylib_pick_2d_polygons",
text='Door',
icon_value=icons["door"].icon_id).action = 'door'
row.operator("archipack.polylib_pick_2d_polygons", text='Rectangle').action = 'rectangle'
row = box.row(align=True)
row.label(text="Lines")
row = box.row(align=True)
row.operator(
"archipack.polylib_pick_2d_lines",
icon_value=icons["selection"].icon_id,
text='Lines').action = 'select'
row.operator(
"archipack.polylib_pick_2d_lines",
icon_value=icons["union"].icon_id,
text='Union').action = 'union'
row.operator(
"archipack.polylib_output_lines",
icon_value=icons["polygons"].icon_id,
text='All')
row = box.row(align=True)
row.label(text="Points")
row = box.row(align=True)
row.operator(
"archipack.polylib_pick_2d_points",
icon_value=icons["selection"].icon_id,
text='Points').action = 'select'
row = layout.row(align=True)
box = row.box()
row = box.row(align=True)
row.operator("archipack.polylib_simplify")
row.prop(context.window_manager.archipack_polylib, "simplify_tolerance")
row = box.row(align=True)
row.prop(context.window_manager.archipack_polylib, "simplify_preserve_topology")
row = layout.row(align=True)
box = row.box()
row = box.row(align=True)
row.operator("archipack.polylib_offset")
row = box.row(align=True)
row.prop(context.window_manager.archipack_polylib, "offset_distance")
row = box.row(align=True)
row.prop(context.window_manager.archipack_polylib, "offset_side")
row = box.row(align=True)
row.prop(context.window_manager.archipack_polylib, "offset_resolution")
row = box.row(align=True)
row.prop(context.window_manager.archipack_polylib, "offset_join_style")
row = box.row(align=True)
row.prop(context.window_manager.archipack_polylib, "offset_mitre_limit")
class TOOLS_PT_Archipack_Tools(Panel):
bl_label = "Archipack Tools"
bl_idname = "TOOLS_PT_Archipack_Tools"
@ -602,7 +461,6 @@ def register():
archipack_door.register()
archipack_window.register()
archipack_stair.register()
archipack_wall.register()
archipack_wall2.register()
archipack_slab.register()
archipack_fence.register()
@ -610,9 +468,6 @@ def register():
archipack_floor.register()
archipack_rendering.register()
if HAS_POLYLIB:
archipack_polylib.register()
bpy.utils.register_class(archipack_data)
WindowManager.archipack = PointerProperty(type=archipack_data)
bpy.utils.register_class(Archipack_Pref)
@ -626,7 +481,6 @@ def unregister():
bpy.types.INFO_MT_mesh_add.remove(menu_func)
bpy.utils.unregister_class(ARCHIPACK_create_menu)
bpy.utils.unregister_class(TOOLS_PT_Archipack_PolyLib)
bpy.utils.unregister_class(TOOLS_PT_Archipack_Tools)
bpy.utils.unregister_class(TOOLS_PT_Archipack_Create)
bpy.utils.unregister_class(Archipack_Pref)
@ -639,7 +493,6 @@ def unregister():
archipack_door.unregister()
archipack_window.unregister()
archipack_stair.unregister()
archipack_wall.unregister()
archipack_wall2.unregister()
archipack_slab.unregister()
archipack_fence.unregister()
@ -647,9 +500,6 @@ def unregister():
archipack_floor.unregister()
archipack_rendering.unregister()
if HAS_POLYLIB:
archipack_polylib.unregister()
bpy.utils.unregister_class(archipack_data)
del WindowManager.archipack

File diff suppressed because it is too large Load Diff

View File

@ -1,137 +0,0 @@
# -*- coding:utf-8 -*-
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110- 1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# ----------------------------------------------------------
# Author: Stephen Leger (s-leger)
#
# ----------------------------------------------------------
import bpy
import bmesh
from bpy.types import Operator, PropertyGroup, Mesh, Panel
from bpy.props import FloatProperty, CollectionProperty
from .archipack_object import ArchipackObject
def update_wall(self, context):
self.update(context)
class archipack_wall(ArchipackObject, PropertyGroup):
z = FloatProperty(
name='height',
min=0.1, max=10000,
default=2.7, precision=2,
description='height', update=update_wall,
)
def update(self, context):
# update height via bmesh to avoid loosing material ids
# this should be the rule for other simple objects
# as long as there is no topologic changes
o = context.active_object
if archipack_wall.datablock(o) != self:
return
bpy.ops.object.mode_set(mode='EDIT')
me = o.data
bm = bmesh.from_edit_mesh(me)
bm.verts.ensure_lookup_table()
bm.faces.ensure_lookup_table()
new_z = self.z
last_z = list(v.co.z for v in bm.verts)
max_z = max(last_z)
for v in bm.verts:
if v.co.z == max_z:
v.co.z = new_z
bmesh.update_edit_mesh(me, True)
bpy.ops.object.mode_set(mode='OBJECT')
class ARCHIPACK_PT_wall(Panel):
bl_idname = "ARCHIPACK_PT_wall"
bl_label = "Wall"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'ArchiPack'
@classmethod
def poll(cls, context):
return archipack_wall.filter(context.active_object)
def draw(self, context):
prop = archipack_wall.datablock(context.active_object)
if prop is None:
return
layout = self.layout
layout.prop(prop, 'z')
# ------------------------------------------------------------------
# Define operator class to create object
# ------------------------------------------------------------------
class ARCHIPACK_OT_wall(Operator):
bl_idname = "archipack.wall"
bl_label = "Wall"
bl_description = "Add wall parameters to active object"
bl_category = 'Archipack'
bl_options = {'REGISTER', 'UNDO'}
z = FloatProperty(
name="z",
default=2.7
)
@classmethod
def poll(cls, context):
return context.active_object is not None
def draw(self, context):
layout = self.layout
row = layout.row()
row.label("Use Properties panel (N) to define parms", icon='INFO')
def execute(self, context):
if context.mode == "OBJECT":
o = context.active_object
if archipack_wall.filter(o):
return {'CANCELLED'}
params = o.data.archipack_wall.add()
params.z = self.z
return {'FINISHED'}
else:
self.report({'WARNING'}, "Archipack: Option only valid in Object mode")
return {'CANCELLED'}
def register():
bpy.utils.register_class(archipack_wall)
Mesh.archipack_wall = CollectionProperty(type=archipack_wall)
bpy.utils.register_class(ARCHIPACK_PT_wall)
bpy.utils.register_class(ARCHIPACK_OT_wall)
def unregister():
bpy.utils.unregister_class(archipack_wall)
del Mesh.archipack_wall
bpy.utils.unregister_class(ARCHIPACK_PT_wall)
bpy.utils.unregister_class(ARCHIPACK_OT_wall)

View File

@ -1,97 +0,0 @@
import array
# -*- coding:utf-8 -*-
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110- 1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# ----------------------------------------------------------
# Author: Stephen Leger (s-leger)
#
# ----------------------------------------------------------
class BitArray():
def __init__(self, bitSize, fill=0):
self.size = bitSize
intSize = bitSize >> 5
if (bitSize & 31):
intSize += 1
if fill == 1:
fill = 4294967295
else:
fill = 0
self.bitArray = array.array('I')
self.bitArray.extend((fill,) * intSize)
def __str__(self):
return str(self.list)
def bit_location(self, bit_num):
return bit_num >> 5, bit_num & 31
def test(self, bit_num):
record, offset = self.bit_location(bit_num)
mask = 1 << offset
return(self.bitArray[record] & mask)
def set(self, bit_num):
record, offset = self.bit_location(bit_num)
mask = 1 << offset
self.bitArray[record] |= mask
def clear(self, bit_num):
record, offset = self.bit_location(bit_num)
mask = ~(1 << offset)
self.bitArray[record] &= mask
def toggle(self, bit_num):
record, offset = self.bit_location(bit_num)
mask = 1 << offset
self.bitArray[record] ^= mask
@property
def len(self):
return len(self.bitArray)
@property
def copy(self):
copy = BitArray(self.size)
for i in range(self.len):
copy.bitArray[i] = self.bitArray[i]
return copy
@property
def list(self):
return [x for x in range(self.size) if self.test(x) > 0]
def none(self):
for i in range(self.len):
self.bitArray[i] = 0
def reverse(self):
for i in range(self.len):
self.bitArray[i] = 4294967295 ^ self.bitArray[i]
def all(self):
for i in range(self.len):
self.bitArray[i] = 4294967295

View File

@ -1,187 +0,0 @@
# -*- coding:utf-8 -*-
# <pep8 compliant>
"""
# Pyqtree
Pyqtree is a pure Python spatial index for GIS or rendering usage.
It stores and quickly retrieves items from a 2x2 rectangular grid area,
and grows in depth and detail as more items are added.
The actual quad tree implementation is adapted from
[Matt Rasmussen's compbio library](https://github.com/mdrasmus/compbio/blob/master/rasmus/quadtree.py)
and extended for geospatial use.
## Platforms
Python 2 and 3.
## Dependencies
Pyqtree is written in pure Python and has no dependencies.
## Installing It
Installing Pyqtree can be done by opening your terminal or commandline and typing:
pip install pyqtree
Alternatively, you can simply download the "pyqtree.py" file and place
it anywhere Python can import it, such as the Python site-packages folder.
## Example Usage
Start your script by importing the quad tree.
from pyqtree import Index
Setup the spatial index, giving it a bounding box area to keep track of.
The bounding box being in a four-tuple: (xmin, ymin, xmax, ymax).
spindex = Index(bbox=(0, 0, 100, 100))
Populate the index with items that you want to be retrieved at a later point,
along with each item's geographic bbox.
# this example assumes you have a list of items with bbox attribute
for item in items:
spindex.insert(item, item.bbox)
Then when you have a region of interest and you wish to retrieve items from that region,
just use the index's intersect method. This quickly gives you a list of the stored items
whose bboxes intersects your region of interests.
overlapbbox = (51, 51, 86, 86)
matches = spindex.intersect(overlapbbox)
There are other things that can be done as well, but that's it for the main usage!
## More Information:
- [Home Page](http://github.com/karimbahgat/Pyqtree)
- [API Documentation](http://pythonhosted.org/Pyqtree)
## License:
This code is free to share, use, reuse, and modify according to the MIT license, see LICENSE.txt.
## Credits:
- Karim Bahgat (2015)
- Joschua Gandert (2016)
"""
__version__ = "0.25.0"
# PYTHON VERSION CHECK
import sys
PYTHON3 = int(sys.version[0]) == 3
if PYTHON3:
xrange = range
class _QuadNode(object):
def __init__(self, item, rect):
self.item = item
self.rect = rect
class _QuadTree(object):
"""
Internal backend version of the index.
The index being used behind the scenes. Has all the same methods as the user
index, but requires more technical arguments when initiating it than the
user-friendly version.
"""
def __init__(self, x, y, width, height, max_items, max_depth, _depth=0):
self.nodes = []
self.children = []
self.center = (x, y)
self.width, self.height = width, height
self.max_items = max_items
self.max_depth = max_depth
self._depth = _depth
def _insert(self, item, bbox):
if len(self.children) == 0:
node = _QuadNode(item, bbox)
self.nodes.append(node)
if len(self.nodes) > self.max_items and self._depth < self.max_depth:
self._split()
else:
self._insert_into_children(item, bbox)
def _intersect(self, rect, results=None):
if results is None:
results = set()
# search children
if self.children:
if rect[0] <= self.center[0]:
if rect[1] <= self.center[1]:
self.children[0]._intersect(rect, results)
if rect[3] >= self.center[1]:
self.children[1]._intersect(rect, results)
if rect[2] >= self.center[0]:
if rect[1] <= self.center[1]:
self.children[2]._intersect(rect, results)
if rect[3] >= self.center[1]:
self.children[3]._intersect(rect, results)
# search node at this level
for node in self.nodes:
if (node.rect[2] >= rect[0] and node.rect[0] <= rect[2] and
node.rect[3] >= rect[1] and node.rect[1] <= rect[3]):
results.add(node.item)
return results
def _insert_into_children(self, item, rect):
# if rect spans center then insert here
if (rect[0] <= self.center[0] and rect[2] >= self.center[0] and
rect[1] <= self.center[1] and rect[3] >= self.center[1]):
node = _QuadNode(item, rect)
self.nodes.append(node)
else:
# try to insert into children
if rect[0] <= self.center[0]:
if rect[1] <= self.center[1]:
self.children[0]._insert(item, rect)
if rect[3] >= self.center[1]:
self.children[1]._insert(item, rect)
if rect[2] > self.center[0]:
if rect[1] <= self.center[1]:
self.children[2]._insert(item, rect)
if rect[3] >= self.center[1]:
self.children[3]._insert(item, rect)
def _split(self):
quartwidth = self.width / 4.0
quartheight = self.height / 4.0
halfwidth = self.width / 2.0
halfheight = self.height / 2.0
x1 = self.center[0] - quartwidth
x2 = self.center[0] + quartwidth
y1 = self.center[1] - quartheight
y2 = self.center[1] + quartheight
new_depth = self._depth + 1
self.children = [_QuadTree(x1, y1, halfwidth, halfheight,
self.max_items, self.max_depth, new_depth),
_QuadTree(x1, y2, halfwidth, halfheight,
self.max_items, self.max_depth, new_depth),
_QuadTree(x2, y1, halfwidth, halfheight,
self.max_items, self.max_depth, new_depth),
_QuadTree(x2, y2, halfwidth, halfheight,
self.max_items, self.max_depth, new_depth)]
nodes = self.nodes
self.nodes = []
for node in nodes:
self._insert_into_children(node.item, node.rect)