Clash results now are sorted and show text overlays of clash type and distance

This commit is contained in:
Dion Moult
2024-03-28 17:11:46 +11:00
parent 924e337c90
commit 68420d43ea
4 changed files with 40 additions and 18 deletions
@@ -16,31 +16,37 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import blf
import gpu import gpu
import bmesh import bmesh
import blenderbim.tool as tool import blenderbim.tool as tool
from bpy.types import SpaceView3D from bpy.types import SpaceView3D
from mathutils import Vector from mathutils import Vector
from gpu_extras.batch import batch_for_shader from gpu_extras.batch import batch_for_shader
from bpy_extras.view3d_utils import location_3d_to_region_2d
class ClashDecorator: class ClashDecorator:
installed = None is_installed = False
handlers = []
@classmethod @classmethod
def install(cls, context): def install(cls, context):
if cls.installed: if cls.is_installed:
cls.uninstall() cls.uninstall()
handler = cls() handler = cls()
cls.installed = SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_VIEW") cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_text, (context,), "WINDOW", "POST_PIXEL"))
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_geometry, (context,), "WINDOW", "POST_VIEW"))
cls.is_installed = True
@classmethod @classmethod
def uninstall(cls): def uninstall(cls):
try: for handler in cls.handlers:
SpaceView3D.draw_handler_remove(cls.installed, "WINDOW") try:
except ValueError: SpaceView3D.draw_handler_remove(handler, "WINDOW")
pass except ValueError:
cls.installed = None pass
cls.is_installed = False
def draw_batch(self, shader_type, content_pos, color, indices=None): def draw_batch(self, shader_type, content_pos, color, indices=None):
shader = self.line_shader if shader_type == "LINES" else self.shader shader = self.line_shader if shader_type == "LINES" else self.shader
@@ -48,7 +54,27 @@ class ClashDecorator:
shader.uniform_float("color", color) shader.uniform_float("color", color)
batch.draw(shader) batch.draw(shader)
def __call__(self, context): def draw_text(self, context):
self.addon_prefs = context.preferences.addons["blenderbim"].preferences
selected_elements_color = self.addon_prefs.decorator_color_selected
unselected_elements_color = self.addon_prefs.decorator_color_unselected
special_elements_color = self.addon_prefs.decorator_color_special
text = context.scene.BIMClashProperties.active_clash_text
p = context.scene.BIMClashProperties.p1.lerp(context.scene.BIMClashProperties.p2, 0.5)
font_id = 0
blf.size(font_id, 12)
coords_2d = location_3d_to_region_2d(context.region, context.region_data, p)
color = self.addon_prefs.decorations_colour
blf.color(font_id, *color)
if coords_2d:
w, h = blf.dimensions(font_id, text)
coords_2d -= Vector((w * .5, 0))
blf.position(font_id, coords_2d[0], coords_2d[1], 0)
blf.draw(font_id, text) # Set your text here
def draw_geometry(self, context):
self.addon_prefs = context.preferences.addons["blenderbim"].preferences self.addon_prefs = context.preferences.addons["blenderbim"].preferences
selected_elements_color = self.addon_prefs.decorator_color_selected selected_elements_color = self.addon_prefs.decorator_color_selected
unselected_elements_color = self.addon_prefs.decorator_color_unselected unselected_elements_color = self.addon_prefs.decorator_color_unselected
@@ -69,6 +69,7 @@ class ImportClashSets(bpy.types.Operator):
def execute(self, context): def execute(self, context):
tool.Clash.load_clash_sets(self.filepath) tool.Clash.load_clash_sets(self.filepath)
context.scene.BIMClashProperties.clash_sets.clear()
for clash_set in tool.Clash.get_clash_sets(): for clash_set in tool.Clash.get_clash_sets():
new = context.scene.BIMClashProperties.clash_sets.add() new = context.scene.BIMClashProperties.clash_sets.add()
new.name = clash_set["name"] new.name = clash_set["name"]
@@ -276,14 +277,7 @@ class ExecuteIfcClash(bpy.types.Operator):
if extension == ".json": if extension == ".json":
tool.Clash.load_clash_sets(self.filepath) tool.Clash.load_clash_sets(self.filepath)
result = tool.Clash.get_clash_set(self.props.active_clash_set.name) tool.Clash.import_active_clashes()
for clash in result["clashes"].values():
blender_clash = self.props.active_clash_set.clashes.add()
blender_clash.a_global_id = clash["a_global_id"]
blender_clash.b_global_id = clash["b_global_id"]
blender_clash.a_name = "{}/{}".format(clash["a_ifc_class"], clash["a_name"])
blender_clash.b_name = "{}/{}".format(clash["b_ifc_class"], clash["b_name"])
blender_clash.status = False if not "status" in clash.keys() else clash["status"]
return {"FINISHED"} return {"FINISHED"}
@@ -379,6 +373,7 @@ class SelectClash(bpy.types.Operator):
tool.Clash.look_at(target, target + Vector((5, 5, 5))) tool.Clash.look_at(target, target + Vector((5, 5, 5)))
self.props.p1 = clash["p1"] self.props.p1 = clash["p1"]
self.props.p2 = clash["p2"] self.props.p2 = clash["p2"]
self.props.active_clash_text = clash["type"].title() + " " + str(round(clash["distance"] * 1000)) + "mm"
return {"FINISHED"} return {"FINISHED"}
@@ -97,6 +97,7 @@ class BIMClashProperties(PropertyGroup):
) )
p1: FloatVectorProperty(name="P1", default=(0.0, 0.0, 0.0), subtype="XYZ") p1: FloatVectorProperty(name="P1", default=(0.0, 0.0, 0.0), subtype="XYZ")
p2: FloatVectorProperty(name="P2", default=(0.0, 0.0, 0.0), subtype="XYZ") p2: FloatVectorProperty(name="P2", default=(0.0, 0.0, 0.0), subtype="XYZ")
active_clash_text: StringProperty(name="Active Clash Text")
@property @property
def active_clash_set(self): def active_clash_set(self):
+1 -1
View File
@@ -80,7 +80,7 @@ class Clash(blenderbim.core.tool.Clash):
return return
clash_set.clashes.clear() clash_set.clashes.clear()
result = tool.Clash.get_clash_set(clash_set.name) result = tool.Clash.get_clash_set(clash_set.name)
for clash in result.get("clashes", {}).values(): for clash in sorted(result.get("clashes", {}).values(), key=lambda x: x["distance"]):
blender_clash = clash_set.clashes.add() blender_clash = clash_set.clashes.add()
blender_clash.a_global_id = clash["a_global_id"] blender_clash.a_global_id = clash["a_global_id"]
blender_clash.b_global_id = clash["b_global_id"] blender_clash.b_global_id = clash["b_global_id"]