Page Menu
Home
Search
Configure Global Search
Log In
Files
F24844
ArToKi_House_Tools.py
Public
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Thierry Maes (tmaes)
Nov 13 2013, 5:21 PM
Size
20 KB
Subscribers
None
ArToKi_House_Tools.py
View Options
# ArToKi-EPB.py (c) 2011 Thierry Maes (tmaes)
#
# ***** 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 LICENCE BLOCK *****
bl_info
=
{
"name"
:
"ArToKi-House-Tools"
,
"author"
:
"Thierry Maes (tmaes)"
,
"version"
:
(
0
,
0
,
6
),
"blender"
:
(
2
,
64
,
0
),
"api"
:
51232
,
"location"
:
"Properties > Object > ArToKi House"
,
"description"
:
"Create houses based on simple 2 point lines."
,
"warning"
:
""
,
"wiki_url"
:
""
,
"tracker_url"
:
""
,
"category"
:
"Object"
}
"""
This addon is made for mass planification.
It scatters and edit simple house primitives.
"""
import
bpy
import
math
from
mathutils
import
Vector
,
Matrix
from
bpy.props
import
*
class
OBJECT_PT_ArToKi_House
(
bpy
.
types
.
Panel
):
bl_label
=
"ArToKi - House - Tools"
bl_space_type
=
"PROPERTIES"
bl_region_type
=
"WINDOW"
bl_context
=
"object"
# Variables
bpy
.
types
.
Scene
.
atk_width
=
bpy
.
props
.
FloatProperty
(
name
=
"House width"
,
description
=
"House width"
,
min
=
0.0
,
max
=
500.0
,
default
=
5.0
,
)
bpy
.
types
.
Scene
.
atk_length
=
bpy
.
props
.
FloatProperty
(
name
=
"House length"
,
description
=
"House length"
,
min
=
0.0
,
max
=
500.0
,
default
=
10.0
,
)
bpy
.
types
.
Scene
.
atk_foundation_height
=
bpy
.
props
.
FloatProperty
(
name
=
"Foundation thickness"
,
description
=
"Foundation Height"
,
min
=
0.0
,
max
=
100.0
,
default
=
0.3
,
)
bpy
.
types
.
Scene
.
atk_ground_floor_height
=
bpy
.
props
.
FloatProperty
(
name
=
"Ground floor height"
,
description
=
"Ground Floor Height"
,
min
=
0.0
,
max
=
10.0
,
default
=
2.5
,
)
bpy
.
types
.
Scene
.
atk_floors_thickness
=
bpy
.
props
.
FloatProperty
(
name
=
"Floors thickness"
,
description
=
"Floors thickness usually 0.3"
,
min
=
0.0
,
max
=
10.0
,
default
=
0.3
,
)
bpy
.
types
.
Scene
.
atk_first_floor_height
=
bpy
.
props
.
FloatProperty
(
name
=
"First floor height"
,
description
=
"House Height"
,
min
=
0.0
,
max
=
10.0
,
default
=
0.0
,
)
bpy
.
types
.
Scene
.
atk_generic_floor_height
=
bpy
.
props
.
FloatProperty
(
name
=
"Generic floor height"
,
description
=
"Second floor height"
,
min
=
0.0
,
max
=
10.0
,
default
=
2.5
,
)
bpy
.
types
.
Scene
.
atk_floors_number
=
bpy
.
props
.
IntProperty
(
name
=
"Number of floors"
,
description
=
"Number of floors"
,
min
=
0
,
max
=
300
,
default
=
1
,
)
bpy
.
types
.
Scene
.
atk_last_floor_height
=
bpy
.
props
.
FloatProperty
(
name
=
"Last floor height"
,
description
=
"Last floor height"
,
min
=
0.0
,
max
=
10.0
,
default
=
0.0
,
)
bpy
.
types
.
Scene
.
atk_cornice_thickness
=
bpy
.
props
.
FloatProperty
(
name
=
"Cornice thickness"
,
description
=
"Last chance to tune the cornice"
,
min
=
0.0
,
max
=
10.0
,
default
=
0.0
,
)
bpy
.
types
.
Scene
.
atk_ridge_height
=
bpy
.
props
.
FloatProperty
(
name
=
"Ridge height"
,
description
=
"Ridge height"
,
min
=
0.0
,
max
=
100.0
,
default
=
3.0
,
)
bpy
.
types
.
Scene
.
atk_walls_thickness
=
bpy
.
props
.
FloatProperty
(
name
=
"Thickness of general exterior walls."
,
description
=
"Thickness of general exterior walls."
,
min
=
0.0
,
max
=
1.0
,
default
=
0.35
,
)
bpy
.
types
.
Scene
.
atk_roof_walls_height
=
bpy
.
props
.
FloatProperty
(
name
=
"Height of general exterior walls."
,
description
=
"Height of general exterior walls."
,
min
=
0.0
,
max
=
1.0
,
default
=
0.5
,
)
bpy
.
types
.
Scene
.
atk_road_parallelism
=
bpy
.
props
.
BoolProperty
(
name
=
"Parallel to the road."
,
description
=
"Is the house parallel to the road."
,
default
=
True
,
)
bpy
.
types
.
Scene
.
atk_create_interior
=
bpy
.
props
.
BoolProperty
(
name
=
"Create interiors."
,
description
=
"Create default ceillings."
,
default
=
False
,
)
# Interface Buttons etc...
def
draw
(
self
,
context
):
layout
=
self
.
layout
obj
=
bpy
.
context
.
object
scene
=
bpy
.
context
.
scene
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_width'
,
text
=
"House width"
)
row
.
prop
(
scene
,
'atk_length'
,
text
=
"House length"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_foundation_height'
,
text
=
"Foundation Height"
)
row
.
prop
(
scene
,
'atk_ground_floor_height'
,
text
=
"Ground floor height"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_floors_thickness'
,
text
=
"Floors thickness"
)
row
.
prop
(
scene
,
'atk_first_floor_height'
,
text
=
"First floor height"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_generic_floor_height'
,
text
=
"Generic floor height"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_floors_number'
,
text
=
"Number of floors"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_last_floor_height'
,
text
=
"Last floor height"
)
row
.
prop
(
scene
,
'atk_cornice_thickness'
,
text
=
"Cornice thickness"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_ridge_height'
,
text
=
"Ridge height"
)
row
.
prop
(
scene
,
'atk_walls_thickness'
,
text
=
"Thickness of general exterior walls"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_road_parallelism'
,
text
=
"Parallel to the road. (Doesn't impact geometry)"
)
row
=
layout
.
row
()
row
.
prop
(
scene
,
'atk_create_interior'
,
text
=
"Create default ceillings"
)
row
=
layout
.
row
()
row
.
operator
(
"object.house_create_houses"
,
text
=
"Create houses from 2 point lines (City Maker)"
)
row
=
layout
.
row
()
row
.
operator
(
"object.house_modify_house_with_settings"
,
text
=
"Modify selected house using parameters"
)
row
=
layout
.
row
()
row
.
operator
(
"object.house_modify_house"
,
text
=
"Modify selected house"
)
class
OBJECT_OT_House_create_houses
(
bpy
.
types
.
Operator
):
bl_label
=
"Create Houses"
bl_idname
=
"object.house_create_houses"
bl_description
=
"Transforms 2 point lines to houses."
@classmethod
def
poll
(
cls
,
context
):
return
context
.
active_object
is
not
None
def
execute
(
self
,
context
):
# main(context)
print
(
64
*
'='
)
### 1- copy the base object in a new temporary one and select it (apply custom properties we will need later, I think)
#bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
scene
=
bpy
.
context
.
scene
obj
=
bpy
.
context
.
object
ver
=
obj
.
data
.
vertices
edg
=
obj
.
data
.
edges
num
=
len
(
edg
)
scene_properties
=
bpy
.
context
.
scene
.
keys
()
if
scene_properties
.
count
(
'house_id'
)
==
0
:
scene
[
'house_id'
]
=
0
# il y a un truc à mettre en rapport avec atk_id ici...
houses_temp
=
[]
bpy
.
ops
.
object
.
mode_set
()
base_object
=
obj
.
name
# delete old temporary mesh
scene_objects
=
scene
.
objects
.
keys
()
bpy
.
ops
.
object
.
select_all
(
action
=
'DESELECT'
)
if
scene_objects
.
count
(
'House_Base'
)
!=
0
:
scene
.
objects
[
'House_Base'
]
.
select
=
True
bpy
.
ops
.
object
.
delete
(
use_global
=
False
)
# cancel sub-object selections in base object
bpy
.
ops
.
object
.
select_all
(
action
=
'DESELECT'
)
scene
.
objects
[
base_object
]
.
select
=
True
bpy
.
ops
.
object
.
duplicate_move
()
bpy
.
context
.
active_object
.
name
=
'House_Base'
bpy
.
ops
.
object
.
select_all
(
action
=
'DESELECT'
)
scene
.
objects
.
active
=
scene
.
objects
[
base_object
]
bpy
.
ops
.
object
.
mode_set
(
mode
=
'EDIT'
)
bpy
.
ops
.
mesh
.
select_all
(
action
=
'DESELECT'
)
bpy
.
ops
.
object
.
mode_set
(
mode
=
'OBJECT'
)
bpy
.
ops
.
object
.
select_all
(
action
=
'DESELECT'
)
# catch the temporary object
scene
.
objects
[
'House_Base'
]
.
select
=
True
scene
.
objects
.
active
=
scene
.
objects
[
'House_Base'
]
### variables update
obj
=
bpy
.
context
.
active_object
ver
=
obj
.
data
.
vertices
edg
=
obj
.
data
.
edges
num
=
len
(
edg
)
#### edges selection mode
# print(obj,edg)
bpy
.
context
.
tool_settings
.
mesh_select_mode
=
[
False
,
True
,
False
]
bpy
.
ops
.
object
.
mode_set
()
for
e
in
edg
:
e
.
use_seam
=
e
.
select
if
e
.
use_seam
:
e
.
select
=
False
# print(norm_pos)
bpy
.
ops
.
object
.
mode_set
(
mode
=
'EDIT'
)
bpy
.
ops
.
mesh
.
select_all
(
action
=
'DESELECT'
)
bpy
.
ops
.
object
.
mode_set
(
mode
=
'OBJECT'
)
for
i
in
range
(
num
):
obj
=
bpy
.
context
.
active_object
edg
=
obj
.
data
.
edges
ver
=
obj
.
data
.
vertices
for
e
in
edg
:
if
e
.
use_seam
:
e
.
select
=
True
e
.
use_seam
=
False
bpy
.
ops
.
object
.
mode_set
(
mode
=
'EDIT'
)
print
(
'youhou'
)
scene
[
'house_id'
]
=
scene
[
'house_id'
]
+
1
bpy
.
ops
.
mesh
.
separate
()
bpy
.
ops
.
object
.
mode_set
(
mode
=
'OBJECT'
)
house_new_name
=
'House_Base_'
+
'
%04d
'
%
(
scene
[
'house_id'
])
bpy
.
context
.
scene
.
objects
[
'House_Base.001'
]
.
name
=
house_new_name
houses_temp
.
append
(
house_new_name
)
break
#
print
(
houses_temp
)
#
#
bpy
.
ops
.
object
.
mode_set
()
bpy
.
ops
.
object
.
select_all
(
action
=
'DESELECT'
)
for
i
in
houses_temp
:
bpy
.
ops
.
object
.
select_all
(
action
=
'DESELECT'
)
bpy
.
data
.
objects
[
i
]
.
select
=
True
scene
.
objects
.
active
=
scene
.
objects
[
i
]
bpy
.
ops
.
object
.
origin_set
(
type
=
'ORIGIN_GEOMETRY'
,
center
=
'MEDIAN'
)
bpy
.
ops
.
transform
.
resize
(
value
=
(
1
,
1
,
0
),
constraint_axis
=
(
False
,
False
,
True
))
bpy
.
ops
.
object
.
transform_apply
(
location
=
True
,
rotation
=
True
,
scale
=
True
)
obj
=
bpy
.
data
.
objects
[
i
]
print
(
obj
)
house_location
=
(
obj
.
data
.
vertices
[
1
]
.
co
[
0
],
obj
.
data
.
vertices
[
1
]
.
co
[
1
],
obj
.
data
.
vertices
[
1
]
.
co
[
2
])
print
(
house_location
)
house_length
=
math
.
hypot
(
obj
.
data
.
vertices
[
0
]
.
co
[
0
]
-
obj
.
data
.
vertices
[
1
]
.
co
[
0
],
obj
.
data
.
vertices
[
0
]
.
co
[
1
]
-
obj
.
data
.
vertices
[
1
]
.
co
[
1
])
vector
=
obj
.
data
.
vertices
[
0
]
.
co
-
obj
.
data
.
vertices
[
1
]
.
co
print
(
vector
)
house_angle
=
math
.
atan2
(
vector
[
1
],
vector
[
0
])
print
(
house_angle
)
bpy
.
ops
.
object
.
delete
(
use_global
=
False
)
bpy
.
ops
.
mesh
.
primitive_house_add
(
True
,
atk_width
=
scene
.
atk_width
,
atk_length
=
house_length
,
atk_foundation_height
=
scene
.
atk_foundation_height
,
atk_ground_floor_height
=
scene
.
atk_ground_floor_height
,
atk_floors_thickness
=
scene
.
atk_floors_thickness
,
atk_first_floor_height
=
scene
.
atk_first_floor_height
,
atk_generic_floor_height
=
scene
.
atk_generic_floor_height
,
atk_floors_number
=
scene
.
atk_floors_number
,
atk_last_floor_height
=
scene
.
atk_last_floor_height
,
atk_cornice_thickness
=
scene
.
atk_cornice_thickness
,
atk_ridge_height
=
scene
.
atk_ridge_height
,
atk_walls_thickness
=
scene
.
atk_walls_thickness
,
atk_roof_walls_height
=
scene
.
atk_roof_walls_height
,
atk_road_parallelism
=
scene
.
atk_road_parallelism
,
atk_create_interior
=
scene
.
atk_create_interior
,
location
=
house_location
,
rotation
=
(
0
,
0
,
house_angle
)
)
bpy
.
ops
.
wm
.
redraw_timer
(
type
=
'DRAW_WIN_SWAP'
,
iterations
=
1
)
# bpy.ops.render.render()
# bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
print
(
i
)
bpy
.
ops
.
object
.
select_all
(
action
=
'DESELECT'
)
scene
.
objects
[
'House_Base'
]
.
select
=
True
bpy
.
ops
.
object
.
delete
(
use_global
=
False
)
return
{
'FINISHED'
}
class
OBJECT_OT_House_modify_house
(
bpy
.
types
.
Operator
):
bl_label
=
"Modify House"
bl_idname
=
"object.house_modify_house"
bl_description
=
"Transforms 2 point lines to houses."
@classmethod
def
poll
(
cls
,
context
):
return
context
.
active_object
is
not
None
def
execute
(
self
,
context
):
# main(context)
print
(
64
*
'='
)
### 1- copy the base object in a new temporary one and select it (apply custom properties we will need later, I think)
scene
=
bpy
.
context
.
scene
obj
=
bpy
.
context
.
object
ver
=
obj
.
data
.
vertices
edg
=
obj
.
data
.
edges
num
=
len
(
edg
)
house_params
=
[]
house_params
.
append
(
obj
[
'atk_Id'
])
#0
house_params
.
append
(
obj
[
'atk_Width'
])
#1
house_params
.
append
(
obj
[
'atk_Length'
])
#2
house_params
.
append
(
obj
[
'atk_Foundation_Height'
])
#3
house_params
.
append
(
obj
[
'atk_Ground_Floor_Height'
])
#4
house_params
.
append
(
obj
[
'atk_Floors_Thickness'
])
#5
house_params
.
append
(
obj
[
'atk_First_Floor_Height'
])
#6
house_params
.
append
(
obj
[
'atk_Generic_Floor_Height'
])
#7
house_params
.
append
(
obj
[
'atk_Floors_Number'
])
#8
house_params
.
append
(
obj
[
'atk_Last_Floor_Height'
])
#9
house_params
.
append
(
obj
[
'atk_Cornice_Thickness'
])
#10
house_params
.
append
(
obj
[
'atk_Ridge_Height'
])
#11
house_params
.
append
(
obj
[
'atk_Walls_Thickness'
])
#12
house_params
.
append
(
obj
[
'atk_Roof_Walls_Height'
])
#13
house_params
.
append
(
obj
[
'atk_Road_Parallelism '
])
#14
house_params
.
append
(
obj
.
location
[
0
])
#15
house_params
.
append
(
obj
.
location
[
1
])
#16
house_params
.
append
(
obj
.
location
[
2
])
#17
house_params
.
append
(
obj
.
rotation_euler
[
2
])
#18
house_params
.
append
(
obj
[
'atk_Create_Interior'
])
#19
bpy
.
ops
.
object
.
delete
()
bpy
.
ops
.
ed
.
undo_push
(
message
=
"Add an undo step *function may be moved*"
)
print
(
house_params
)
bpy
.
ops
.
mesh
.
primitive_house_add
(
True
,
atk_width
=
house_params
[
1
],
atk_length
=
house_params
[
2
],
atk_foundation_height
=
house_params
[
3
],
atk_ground_floor_height
=
house_params
[
4
],
atk_floors_thickness
=
house_params
[
5
],
atk_first_floor_height
=
house_params
[
6
],
atk_generic_floor_height
=
house_params
[
7
],
atk_floors_number
=
house_params
[
8
],
atk_last_floor_height
=
house_params
[
9
],
atk_cornice_thickness
=
house_params
[
10
],
atk_ridge_height
=
house_params
[
11
],
atk_walls_thickness
=
house_params
[
12
],
atk_roof_walls_height
=
house_params
[
13
],
atk_road_parallelism
=
house_params
[
14
],
location
=
(
house_params
[
15
],
house_params
[
16
],
house_params
[
17
]),
rotation
=
(
0
,
0
,
house_params
[
18
]),
atk_create_interior
=
house_params
[
19
]
)
return
{
'FINISHED'
}
class
OBJECT_OT_House_modify_house_with_settings
(
bpy
.
types
.
Operator
):
bl_label
=
"Modify House with settings"
bl_idname
=
"object.house_modify_house_with_settings"
bl_description
=
"Modify a house with parameters"
@classmethod
def
poll
(
cls
,
context
):
return
context
.
active_object
is
not
None
def
execute
(
self
,
context
):
# main(context)
print
(
64
*
'='
)
### 1- copy the base object in a new temporary one and select it (apply custom properties we will need later, I think)
scene
=
bpy
.
context
.
scene
obj
=
bpy
.
context
.
object
ver
=
obj
.
data
.
vertices
edg
=
obj
.
data
.
edges
num
=
len
(
edg
)
house_params
=
[]
house_params
.
append
(
obj
[
'atk_Id'
])
#0
house_params
.
append
(
obj
[
'atk_Width'
])
#1
house_params
.
append
(
obj
[
'atk_Length'
])
#2
house_params
.
append
(
obj
[
'atk_Foundation_Height'
])
#3
house_params
.
append
(
obj
[
'atk_Ground_Floor_Height'
])
#4
house_params
.
append
(
obj
[
'atk_Floors_Thickness'
])
#5
house_params
.
append
(
obj
[
'atk_First_Floor_Height'
])
#6
house_params
.
append
(
obj
[
'atk_Generic_Floor_Height'
])
#7
house_params
.
append
(
obj
[
'atk_Floors_Number'
])
#8
house_params
.
append
(
obj
[
'atk_Last_Floor_Height'
])
#9
house_params
.
append
(
obj
[
'atk_Cornice_Thickness'
])
#10
house_params
.
append
(
obj
[
'atk_Ridge_Height'
])
#11
house_params
.
append
(
obj
[
'atk_Walls_Thickness'
])
#12
house_params
.
append
(
obj
[
'atk_Roof_Walls_Height'
])
#13
house_params
.
append
(
obj
[
'atk_Road_Parallelism '
])
#14
house_params
.
append
(
obj
.
location
[
0
])
#15
house_params
.
append
(
obj
.
location
[
1
])
#16
house_params
.
append
(
obj
.
location
[
2
])
#17
house_params
.
append
(
obj
.
rotation_euler
[
2
])
#18
house_params
.
append
(
obj
[
'atk_Create_Interior'
])
#19
bpy
.
ops
.
object
.
delete
(
use_global
=
False
)
print
(
house_params
)
bpy
.
ops
.
mesh
.
primitive_house_add
(
True
,
atk_width
=
scene
.
atk_width
,
atk_length
=
scene
.
atk_length
,
atk_foundation_height
=
scene
.
atk_foundation_height
,
atk_ground_floor_height
=
scene
.
atk_ground_floor_height
,
atk_floors_thickness
=
scene
.
atk_floors_thickness
,
atk_first_floor_height
=
scene
.
atk_first_floor_height
,
atk_generic_floor_height
=
scene
.
atk_generic_floor_height
,
atk_floors_number
=
scene
.
atk_floors_number
,
atk_last_floor_height
=
scene
.
atk_last_floor_height
,
atk_cornice_thickness
=
scene
.
atk_cornice_thickness
,
atk_ridge_height
=
scene
.
atk_ridge_height
,
atk_walls_thickness
=
scene
.
atk_walls_thickness
,
atk_roof_walls_height
=
scene
.
atk_roof_walls_height
,
atk_road_parallelism
=
scene
.
atk_road_parallelism
,
location
=
(
house_params
[
15
],
house_params
[
16
],
house_params
[
17
]),
rotation
=
(
0
,
0
,
house_params
[
18
]),
atk_create_interior
=
house_params
[
19
]
)
return
{
'FINISHED'
}
# registering and menu integration
def
register
():
bpy
.
utils
.
register_class
(
OBJECT_PT_ArToKi_House
)
bpy
.
utils
.
register_class
(
OBJECT_OT_House_create_houses
)
bpy
.
utils
.
register_class
(
OBJECT_OT_House_modify_house
)
bpy
.
utils
.
register_class
(
OBJECT_OT_House_modify_house_with_settings
)
# unregistering and removing menus
def
unregister
():
bpy
.
utils
.
unregister_class
(
OBJECT_PT_ArToKi_House
)
bpy
.
utils
.
unregister_class
(
OBJECT_OT_House_create_houses
)
bpy
.
utils
.
unregister_class
(
OBJECT_OT_House_modify_house
)
bpy
.
utils
.
unregister_class
(
OBJECT_OT_House_modify_house_with_settings
)
if
__name__
==
"__main__"
:
register
()
File Metadata
Details
Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
60/d7/e5acf71c861bdea5e34a99e7176f
Event Timeline
Log In to Comment