Add aggregate mode decorator.

This commit is contained in:
Bruno Perdigão
2024-11-25 17:46:48 -03:00
committed by Bruno Perdigão
parent 3c590f097a
commit 226ea10de8
2 changed files with 102 additions and 22 deletions
@@ -16,15 +16,22 @@
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import blf
import bpy
import gpu
import ifcopenshell
import bonsai.tool as tool
from bpy.types import SpaceView3D
from bpy_extras import view3d_utils
from gpu_extras.batch import batch_for_shader
from mathutils import Vector
def transparent_color(color, alpha=0.1):
color = [i for i in color]
color[3] = alpha
return color
class AggregateDecorator:
is_installed = False
handlers = []
@@ -47,23 +54,19 @@ class AggregateDecorator:
pass
cls.is_installed = False
def transparent_color(self, color, alpha=0.1):
color = [i for i in color]
color[3] = alpha
return color
def dotted_line_shader(self):
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
vert_out.smooth('FLOAT', "v_ArcLength")
vert_out.smooth("FLOAT", "v_ArcLength")
shader_info = gpu.types.GPUShaderCreateInfo()
shader_info.push_constant('MAT4', "u_ViewProjectionMatrix")
shader_info.push_constant('FLOAT', "u_Scale")
shader_info.vertex_in(0, 'VEC3', "position")
shader_info.vertex_in(1, 'FLOAT', "arcLength")
shader_info.push_constant("MAT4", "u_ViewProjectionMatrix")
shader_info.push_constant("FLOAT", "u_Scale")
shader_info.vertex_in(0, "VEC3", "position")
shader_info.vertex_in(1, "FLOAT", "arcLength")
shader_info.vertex_out(vert_out)
shader_info.fragment_out(0, 'VEC4', "FragColor")
shader_info.push_constant('VEC4', "color")
shader_info.fragment_out(0, "VEC4", "FragColor")
shader_info.push_constant("VEC4", "color")
shader_info.vertex_source(
"void main()"
@@ -74,11 +77,7 @@ class AggregateDecorator:
)
shader_info.fragment_source(
"void main()"
"{"
" if (step(sin(v_ArcLength * u_Scale), 0.4) == 1) discard;"
" FragColor = color;"
"}"
"void main()" "{" " if (step(sin(v_ArcLength * u_Scale), 0.4) == 1) discard;" " FragColor = color;" "}"
)
shader = gpu.shader.create_from_info(shader_info)
@@ -86,7 +85,6 @@ class AggregateDecorator:
del shader_info
return shader
def draw_custom_batch(self, coords, color):
shader = self.dotted_line_shader()
@@ -95,7 +93,8 @@ class AggregateDecorator:
arc_lengths.append(arc_lengths[-1] + (a - b).length)
batch = batch_for_shader(
shader, 'LINE_STRIP',
shader,
"LINE_STRIP",
{"position": coords, "arcLength": arc_lengths},
)
@@ -105,7 +104,6 @@ class AggregateDecorator:
shader.uniform_float("u_Scale", 25)
batch.draw(shader)
def draw_batch(self, shader_type, content_pos, color, indices=None):
shader = self.line_shader if shader_type == "LINES" else self.shader
batch = batch_for_shader(shader, shader_type, {"pos": content_pos}, indices=indices)
@@ -156,10 +154,91 @@ class AggregateDecorator:
self.draw_batch("LINES", line_y, color, [(0, 1)])
line_z = (location - Vector((0.0, 0.0, size)), location + Vector((0.0, 0.0, size)))
self.draw_batch("LINES", line_z, color, [(0, 1)])
if context.scene.BIMAggregateProperties.in_edit_mode:
if context.scene.BIMAggregateProperties.in_aggregate_mode:
return
parts = ifcopenshell.util.element.get_parts(tool.Ifc.get_entity(aggregate))
for part in parts:
part_obj = tool.Ifc.get_object(part)
line = (part_obj.matrix_world.translation, location)
self.draw_custom_batch(line, decorator_color_unselected)
class AggregateModeDecorator:
is_installed = False
handlers = []
@classmethod
def install(cls, context):
if cls.is_installed:
cls.uninstall()
handler = cls()
cls.handlers.append(
SpaceView3D.draw_handler_add(handler.draw_aggregate_name, (context,), "WINDOW", "POST_PIXEL")
)
cls.handlers.append(
SpaceView3D.draw_handler_add(handler.draw_aggregate_empty, (context,), "WINDOW", "POST_VIEW")
)
cls.is_installed = True
@classmethod
def uninstall(cls):
for handler in cls.handlers:
try:
SpaceView3D.draw_handler_remove(handler, "WINDOW")
except ValueError:
pass
cls.is_installed = False
def draw_batch(self, shader_type, content_pos, color, indices=None):
shader = self.line_shader if shader_type == "LINES" else self.shader
batch = batch_for_shader(shader, shader_type, {"pos": content_pos}, indices=indices)
shader.uniform_float("color", color)
batch.draw(shader)
def draw_aggregate_name(self, context):
region = context.region
rv3d = region.data
props = context.scene.BIMAggregateProperties
aggregate_obj = props.editing_aggregate
self.addon_prefs = tool.Blender.get_addon_preferences()
self.font_id = 0
font_size = tool.Blender.scale_font_size(12)
blf.size(self.font_id, font_size)
blf.enable(self.font_id, blf.SHADOW)
blf.shadow(self.font_id, 6, 0, 0, 0, 1)
color = self.addon_prefs.decorator_color_special
if aggregate_obj in context.selected_objects:
color = self.addon_prefs.decorator_color_selected
blf.color(self.font_id, *color)
text = aggregate_obj.name
text_coords = view3d_utils.location_3d_to_region_2d(region, rv3d, aggregate_obj.location)
text_length = blf.dimensions(self.font_id, text)
text_coords[0] -= (text_length[0] / 2)
text_coords[1] -= 20
blf.position(self.font_id, text_coords[0], text_coords[1], 0)
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
blf.draw(self.font_id, text)
def draw_aggregate_empty(self, context):
props = context.scene.BIMAggregateProperties
aggregate_obj = props.editing_aggregate
self.addon_prefs = tool.Blender.get_addon_preferences()
self.line_shader = gpu.shader.from_builtin("POLYLINE_UNIFORM_COLOR")
self.line_shader.bind()
self.line_shader.uniform_float("viewportSize", (context.region.width, context.region.height))
self.line_shader.uniform_float("lineWidth", 1.0)
color = self.addon_prefs.decorator_color_special
if aggregate_obj in context.selected_objects:
self.line_shader.uniform_float("lineWidth", 2.0)
color = self.addon_prefs.decorator_color_selected
size = aggregate_obj.empty_display_size
location = aggregate_obj.location
line_x = (location - Vector((size, 0.0, 0.0)), location + Vector((size, 0.0, 0.0)))
self.draw_batch("LINES", line_x, color, [(0, 1)])
line_y = (location - Vector((0.0, size, 0.0)), location + Vector((0.0, size, 0.0)))
self.draw_batch("LINES", line_y, color, [(0, 1)])
line_z = (location - Vector((0.0, 0.0, size)), location + Vector((0.0, 0.0, size)))
self.draw_batch("LINES", line_z, color, [(0, 1)])
@@ -24,6 +24,7 @@ import bonsai.tool as tool
import bonsai.core.aggregate as core
import bonsai.core.spatial
from bonsai.bim.ifc import IfcStore
from bonsai.bim.module.aggregate.decorator import AggregateModeDecorator
class BIM_OT_aggregate_assign_object(bpy.types.Operator, tool.Ifc.Operator):
@@ -388,10 +389,10 @@ class BIM_OT_toggle_mode_set_aggregate(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context):
props = context.scene.BIMAggregateProperties
if props.in_aggregate_mode:
#AggregateModeDecorator.uninstall()
AggregateModeDecorator.uninstall()
BIM_OT_disable_mode_set_aggregate._execute(self, context)
else:
#AggregateModeDecorator.install(context)
AggregateModeDecorator.install(context)
BIM_OT_mode_set_aggregate._execute(self, context)