mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 14:02:27 +00:00
No new functionality. Just throwing all drawing code in the drawing module. See #1153.
This commit is contained in:
@@ -6,7 +6,7 @@ bpy = sys.modules.get("bpy")
|
|||||||
if bpy is not None:
|
if bpy is not None:
|
||||||
import bpy
|
import bpy
|
||||||
import importlib
|
import importlib
|
||||||
from . import handler, ui, prop, operator, gizmos
|
from . import handler, ui, prop, operator
|
||||||
|
|
||||||
modules = {
|
modules = {
|
||||||
"project": None,
|
"project": None,
|
||||||
@@ -63,50 +63,18 @@ if bpy is not None:
|
|||||||
operator.SelectExternalMaterialDir,
|
operator.SelectExternalMaterialDir,
|
||||||
operator.FetchExternalMaterial,
|
operator.FetchExternalMaterial,
|
||||||
operator.FetchObjectPassport,
|
operator.FetchObjectPassport,
|
||||||
operator.CutSection,
|
|
||||||
operator.AddSheet,
|
|
||||||
operator.OpenSheet,
|
|
||||||
operator.AddDrawingToSheet,
|
|
||||||
operator.CreateSheets,
|
|
||||||
operator.OpenView,
|
|
||||||
operator.OpenViewCamera,
|
|
||||||
operator.ActivateView,
|
|
||||||
operator.OpenUpstream,
|
operator.OpenUpstream,
|
||||||
operator.AddSectionPlane,
|
operator.AddSectionPlane,
|
||||||
operator.RemoveSectionPlane,
|
operator.RemoveSectionPlane,
|
||||||
operator.ReloadIfcFile,
|
operator.ReloadIfcFile,
|
||||||
operator.AddIfcFile,
|
operator.AddIfcFile,
|
||||||
operator.RemoveIfcFile,
|
operator.RemoveIfcFile,
|
||||||
operator.SelectDocIfcFile,
|
|
||||||
operator.GenerateReferences,
|
|
||||||
operator.ResizeText,
|
|
||||||
operator.AddVariable,
|
|
||||||
operator.RemoveVariable,
|
|
||||||
operator.PropagateTextData,
|
|
||||||
operator.SetOverrideColour,
|
operator.SetOverrideColour,
|
||||||
operator.RemoveDrawing,
|
|
||||||
operator.AddDrawingStyle,
|
|
||||||
operator.RemoveDrawingStyle,
|
|
||||||
operator.SaveDrawingStyle,
|
|
||||||
operator.ActivateDrawingStyle,
|
|
||||||
operator.EditVectorStyle,
|
|
||||||
operator.RemoveSheet,
|
|
||||||
operator.AddSchedule,
|
|
||||||
operator.RemoveSchedule,
|
|
||||||
operator.SelectScheduleFile,
|
|
||||||
operator.BuildSchedule,
|
|
||||||
operator.AddScheduleToSheet,
|
|
||||||
operator.SetViewportShadowFromSun,
|
operator.SetViewportShadowFromSun,
|
||||||
operator.AddDrawingStyleAttribute,
|
|
||||||
operator.RemoveDrawingStyleAttribute,
|
|
||||||
operator.CopyPropertyToSelection,
|
operator.CopyPropertyToSelection,
|
||||||
operator.CopyAttributeToSelection,
|
operator.CopyAttributeToSelection,
|
||||||
operator.RefreshDrawingList,
|
|
||||||
operator.CleanWireframes,
|
|
||||||
operator.LinkIfc,
|
operator.LinkIfc,
|
||||||
operator.SnapSpacesTogether,
|
operator.SnapSpacesTogether,
|
||||||
operator.CopyGrid,
|
|
||||||
operator.AddSectionsAnnotations,
|
|
||||||
prop.StrProperty,
|
prop.StrProperty,
|
||||||
prop.Attribute,
|
prop.Attribute,
|
||||||
prop.BIMProperties,
|
prop.BIMProperties,
|
||||||
@@ -118,21 +86,10 @@ if bpy is not None:
|
|||||||
prop.ItemSlotMap,
|
prop.ItemSlotMap,
|
||||||
prop.BIMMeshProperties,
|
prop.BIMMeshProperties,
|
||||||
ui.BIM_PT_section_plane,
|
ui.BIM_PT_section_plane,
|
||||||
ui.BIM_PT_drawings,
|
|
||||||
ui.BIM_PT_schedules,
|
|
||||||
ui.BIM_PT_sheets,
|
|
||||||
ui.BIM_PT_text,
|
|
||||||
ui.BIM_PT_annotation_utilities,
|
|
||||||
ui.BIM_PT_misc_utilities,
|
ui.BIM_PT_misc_utilities,
|
||||||
ui.BIM_UL_generic,
|
ui.BIM_UL_generic,
|
||||||
ui.BIM_UL_drawinglist,
|
|
||||||
ui.BIM_UL_topics,
|
ui.BIM_UL_topics,
|
||||||
ui.BIM_ADDON_preferences,
|
ui.BIM_ADDON_preferences,
|
||||||
gizmos.UglyDotGizmo,
|
|
||||||
gizmos.DotGizmo,
|
|
||||||
gizmos.DimensionLabelGizmo,
|
|
||||||
gizmos.ExtrusionGuidesGizmo,
|
|
||||||
gizmos.ExtrusionWidget
|
|
||||||
]
|
]
|
||||||
|
|
||||||
for module in modules.values():
|
for module in modules.values():
|
||||||
@@ -160,7 +117,9 @@ if bpy is not None:
|
|||||||
bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties)
|
bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties)
|
||||||
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
||||||
bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
||||||
bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) # Check if we need this
|
bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty(
|
||||||
|
type=prop.BIMObjectProperties
|
||||||
|
) # Check if we need this
|
||||||
bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
|
bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
|
||||||
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
|
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
|
||||||
bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
|
bpy.types.Curve.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
|
||||||
@@ -170,8 +129,6 @@ if bpy is not None:
|
|||||||
for module in modules.values():
|
for module in modules.values():
|
||||||
module.register()
|
module.register()
|
||||||
|
|
||||||
bpy.app.handlers.depsgraph_update_pre.append(operator.depsgraph_update_pre_handler)
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
for cls in reversed(classes):
|
for cls in reversed(classes):
|
||||||
bpy.utils.unregister_class(cls)
|
bpy.utils.unregister_class(cls)
|
||||||
@@ -183,7 +140,7 @@ if bpy is not None:
|
|||||||
del bpy.types.Scene.BIMProperties
|
del bpy.types.Scene.BIMProperties
|
||||||
del bpy.types.Object.BIMObjectProperties
|
del bpy.types.Object.BIMObjectProperties
|
||||||
del bpy.types.Material.BIMObjectProperties
|
del bpy.types.Material.BIMObjectProperties
|
||||||
del bpy.types.Collection.BIMObjectProperties # Check if we need this
|
del bpy.types.Collection.BIMObjectProperties # Check if we need this
|
||||||
del bpy.types.Material.BIMMaterialProperties
|
del bpy.types.Material.BIMMaterialProperties
|
||||||
del bpy.types.Mesh.BIMMeshProperties
|
del bpy.types.Mesh.BIMMeshProperties
|
||||||
del bpy.types.Curve.BIMMeshProperties
|
del bpy.types.Curve.BIMMeshProperties
|
||||||
@@ -192,5 +149,3 @@ if bpy is not None:
|
|||||||
|
|
||||||
for module in reversed(list(modules.values())):
|
for module in reversed(list(modules.values())):
|
||||||
module.unregister()
|
module.unregister()
|
||||||
|
|
||||||
bpy.app.handlers.depsgraph_update_pre.remove(operator.depsgraph_update_pre_handler)
|
|
||||||
|
|||||||
@@ -1,10 +1,42 @@
|
|||||||
import bpy
|
import bpy
|
||||||
from . import ui, prop, operator, handler
|
from . import ui, prop, operator, handler, gizmos
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
operator.AddDrawing,
|
operator.AddDrawing,
|
||||||
operator.CreateDrawing,
|
operator.CreateDrawing,
|
||||||
operator.AddAnnotation,
|
operator.AddAnnotation,
|
||||||
|
operator.CutSection, # TODO: To deprecate
|
||||||
|
operator.AddSheet,
|
||||||
|
operator.OpenSheet,
|
||||||
|
operator.AddDrawingToSheet,
|
||||||
|
operator.CreateSheets,
|
||||||
|
operator.OpenView,
|
||||||
|
operator.OpenViewCamera,
|
||||||
|
operator.ActivateView,
|
||||||
|
operator.SelectDocIfcFile,
|
||||||
|
operator.GenerateReferences,
|
||||||
|
operator.ResizeText,
|
||||||
|
operator.AddVariable,
|
||||||
|
operator.RemoveVariable,
|
||||||
|
operator.PropagateTextData,
|
||||||
|
operator.RemoveDrawing,
|
||||||
|
operator.AddDrawingStyle,
|
||||||
|
operator.RemoveDrawingStyle,
|
||||||
|
operator.SaveDrawingStyle,
|
||||||
|
operator.ActivateDrawingStyle,
|
||||||
|
operator.EditVectorStyle,
|
||||||
|
operator.RemoveSheet,
|
||||||
|
operator.AddSchedule,
|
||||||
|
operator.RemoveSchedule,
|
||||||
|
operator.SelectScheduleFile,
|
||||||
|
operator.BuildSchedule,
|
||||||
|
operator.AddScheduleToSheet,
|
||||||
|
operator.AddDrawingStyleAttribute,
|
||||||
|
operator.RemoveDrawingStyleAttribute,
|
||||||
|
operator.RefreshDrawingList,
|
||||||
|
operator.CleanWireframes,
|
||||||
|
operator.CopyGrid,
|
||||||
|
operator.AddSectionsAnnotations,
|
||||||
prop.Variable,
|
prop.Variable,
|
||||||
prop.Drawing,
|
prop.Drawing,
|
||||||
prop.Schedule,
|
prop.Schedule,
|
||||||
@@ -14,6 +46,17 @@ classes = (
|
|||||||
prop.BIMCameraProperties,
|
prop.BIMCameraProperties,
|
||||||
prop.BIMTextProperties,
|
prop.BIMTextProperties,
|
||||||
ui.BIM_PT_camera,
|
ui.BIM_PT_camera,
|
||||||
|
ui.BIM_PT_drawings,
|
||||||
|
ui.BIM_PT_schedules,
|
||||||
|
ui.BIM_PT_sheets,
|
||||||
|
ui.BIM_PT_text,
|
||||||
|
ui.BIM_PT_annotation_utilities,
|
||||||
|
ui.BIM_UL_drawinglist,
|
||||||
|
gizmos.UglyDotGizmo,
|
||||||
|
gizmos.DotGizmo,
|
||||||
|
gizmos.DimensionLabelGizmo,
|
||||||
|
gizmos.ExtrusionGuidesGizmo,
|
||||||
|
gizmos.ExtrusionWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -22,6 +65,7 @@ def register():
|
|||||||
bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties)
|
bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties)
|
||||||
bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties)
|
bpy.types.TextCurve.BIMTextProperties = bpy.props.PointerProperty(type=prop.BIMTextProperties)
|
||||||
bpy.app.handlers.load_post.append(handler.toggleDecorationsOnLoad)
|
bpy.app.handlers.load_post.append(handler.toggleDecorationsOnLoad)
|
||||||
|
bpy.app.handlers.depsgraph_update_pre.append(handler.depsgraph_update_pre_handler)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
@@ -29,3 +73,4 @@ def unregister():
|
|||||||
del bpy.types.Camera.BIMCameraProperties
|
del bpy.types.Camera.BIMCameraProperties
|
||||||
del bpy.types.TextCurve.BIMTextProperties
|
del bpy.types.TextCurve.BIMTextProperties
|
||||||
bpy.app.handlers.load_post.remove(handler.toggleDecorationsOnLoad)
|
bpy.app.handlers.load_post.remove(handler.toggleDecorationsOnLoad)
|
||||||
|
bpy.app.handlers.depsgraph_update_pre.remove(handler.depsgraph_update_pre_handler)
|
||||||
|
|||||||
+235
-122
@@ -1,14 +1,12 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import blf
|
import blf
|
||||||
from bpy import types
|
|
||||||
import math
|
import math
|
||||||
|
import gpu, bgl
|
||||||
|
from bpy import types
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from mathutils import geometry
|
from mathutils import geometry
|
||||||
import gpu, bgl
|
|
||||||
from bpy_extras import view3d_utils
|
from bpy_extras import view3d_utils
|
||||||
|
from blenderbim.bim.module.drawing.shaders import DotsGizmoShader, ExtrusionGuidesShader, BaseLinesShader
|
||||||
|
|
||||||
from .shaders import DotsGizmoShader, ExtrusionGuidesShader, BaseLinesShader
|
|
||||||
|
|
||||||
|
|
||||||
"""Gizmos under the hood
|
"""Gizmos under the hood
|
||||||
@@ -43,76 +41,196 @@ draw_select -- fake-draw of selection geometry for gpu-side cursor tracking
|
|||||||
# some geometries for Gizmo.custom_shape shaders
|
# some geometries for Gizmo.custom_shape shaders
|
||||||
|
|
||||||
CUBE = (
|
CUBE = (
|
||||||
(+1, +1, +1), (-1, +1, +1), (+1, -1, +1), # top
|
(+1, +1, +1),
|
||||||
(+1, -1, +1), (-1, +1, +1), (-1, -1, +1),
|
(-1, +1, +1),
|
||||||
(+1, +1, +1), (+1, -1, +1), (+1, +1, -1), # right
|
(+1, -1, +1), # top
|
||||||
(+1, +1, -1), (+1, -1, +1), (+1, -1, -1),
|
(+1, -1, +1),
|
||||||
(+1, +1, +1), (+1, +1, -1), (-1, +1, +1), # back
|
(-1, +1, +1),
|
||||||
(-1, +1, +1), (+1, +1, -1), (-1, +1, -1),
|
(-1, -1, +1),
|
||||||
(-1, -1, -1), (-1, +1, -1), (+1, -1, -1), # bot
|
(+1, +1, +1),
|
||||||
(+1, -1, -1), (-1, +1, -1), (+1, +1, -1),
|
(+1, -1, +1),
|
||||||
(-1, -1, -1), (-1, -1, +1), (-1, +1, -1), # left
|
(+1, +1, -1), # right
|
||||||
(-1, +1, -1), (-1, -1, +1), (-1, +1, +1),
|
(+1, +1, -1),
|
||||||
(-1, -1, -1), (+1, -1, -1), (-1, -1, +1), # front
|
(+1, -1, +1),
|
||||||
(-1, -1, +1), (+1, -1, -1), (+1, -1, +1)
|
(+1, -1, -1),
|
||||||
|
(+1, +1, +1),
|
||||||
|
(+1, +1, -1),
|
||||||
|
(-1, +1, +1), # back
|
||||||
|
(-1, +1, +1),
|
||||||
|
(+1, +1, -1),
|
||||||
|
(-1, +1, -1),
|
||||||
|
(-1, -1, -1),
|
||||||
|
(-1, +1, -1),
|
||||||
|
(+1, -1, -1), # bot
|
||||||
|
(+1, -1, -1),
|
||||||
|
(-1, +1, -1),
|
||||||
|
(+1, +1, -1),
|
||||||
|
(-1, -1, -1),
|
||||||
|
(-1, -1, +1),
|
||||||
|
(-1, +1, -1), # left
|
||||||
|
(-1, +1, -1),
|
||||||
|
(-1, -1, +1),
|
||||||
|
(-1, +1, +1),
|
||||||
|
(-1, -1, -1),
|
||||||
|
(+1, -1, -1),
|
||||||
|
(-1, -1, +1), # front
|
||||||
|
(-1, -1, +1),
|
||||||
|
(+1, -1, -1),
|
||||||
|
(+1, -1, +1),
|
||||||
)
|
)
|
||||||
|
|
||||||
DISC = (
|
DISC = (
|
||||||
(0.0, 0.0, 0.0), (1.0, 0.0, 0), (0.8660254037844387, 0.49999999999999994, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0.8660254037844387, 0.49999999999999994, 0), (0.5000000000000001, 0.8660254037844386, 0),
|
(1.0, 0.0, 0),
|
||||||
(0.0, 0.0, 0.0), (0.5000000000000001, 0.8660254037844386, 0), (6.123233995736766e-17, 1.0, 0),
|
(0.8660254037844387, 0.49999999999999994, 0),
|
||||||
(0.0, 0.0, 0.0), (6.123233995736766e-17, 1.0, 0), (-0.4999999999999998, 0.8660254037844387, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (-0.4999999999999998, 0.8660254037844387, 0), (-0.8660254037844385, 0.5000000000000003, 0),
|
(0.8660254037844387, 0.49999999999999994, 0),
|
||||||
(0.0, 0.0, 0.0), (-0.8660254037844385, 0.5000000000000003, 0), (-1.0, 1.2246467991473532e-16, 0),
|
(0.5000000000000001, 0.8660254037844386, 0),
|
||||||
(0.0, 0.0, 0.0), (-1.0, 1.2246467991473532e-16, 0), (-0.8660254037844388, -0.4999999999999997, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (-0.8660254037844388, -0.4999999999999997, 0), (-0.5000000000000004, -0.8660254037844384, 0),
|
(0.5000000000000001, 0.8660254037844386, 0),
|
||||||
(0.0, 0.0, 0.0), (-0.5000000000000004, -0.8660254037844384, 0), (-1.8369701987210297e-16, -1.0, 0),
|
(6.123233995736766e-17, 1.0, 0),
|
||||||
(0.0, 0.0, 0.0), (-1.8369701987210297e-16, -1.0, 0), (0.49999999999999933, -0.866025403784439, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0.49999999999999933, -0.866025403784439, 0), (0.8660254037844384, -0.5000000000000004, 0),
|
(6.123233995736766e-17, 1.0, 0),
|
||||||
(0.0, 0.0, 0.0), (0.8660254037844384, -0.5000000000000004, 0), (1.0, 0.0, 0),
|
(-0.4999999999999998, 0.8660254037844387, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.4999999999999998, 0.8660254037844387, 0),
|
||||||
|
(-0.8660254037844385, 0.5000000000000003, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.8660254037844385, 0.5000000000000003, 0),
|
||||||
|
(-1.0, 1.2246467991473532e-16, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-1.0, 1.2246467991473532e-16, 0),
|
||||||
|
(-0.8660254037844388, -0.4999999999999997, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.8660254037844388, -0.4999999999999997, 0),
|
||||||
|
(-0.5000000000000004, -0.8660254037844384, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.5000000000000004, -0.8660254037844384, 0),
|
||||||
|
(-1.8369701987210297e-16, -1.0, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-1.8369701987210297e-16, -1.0, 0),
|
||||||
|
(0.49999999999999933, -0.866025403784439, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0.49999999999999933, -0.866025403784439, 0),
|
||||||
|
(0.8660254037844384, -0.5000000000000004, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0.8660254037844384, -0.5000000000000004, 0),
|
||||||
|
(1.0, 0.0, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
X3DISC = (
|
X3DISC = (
|
||||||
(0.0, 0.0, 0.0), (1.0, 0.0, 0), (0.8660254037844387, 0.49999999999999994, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0.8660254037844387, 0.49999999999999994, 0), (0.5000000000000001, 0.8660254037844386, 0),
|
(1.0, 0.0, 0),
|
||||||
(0.0, 0.0, 0.0), (0.5000000000000001, 0.8660254037844386, 0), (6.123233995736766e-17, 1.0, 0),
|
(0.8660254037844387, 0.49999999999999994, 0),
|
||||||
(0.0, 0.0, 0.0), (6.123233995736766e-17, 1.0, 0), (-0.4999999999999998, 0.8660254037844387, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (-0.4999999999999998, 0.8660254037844387, 0), (-0.8660254037844385, 0.5000000000000003, 0),
|
(0.8660254037844387, 0.49999999999999994, 0),
|
||||||
(0.0, 0.0, 0.0), (-0.8660254037844385, 0.5000000000000003, 0), (-1.0, 1.2246467991473532e-16, 0),
|
(0.5000000000000001, 0.8660254037844386, 0),
|
||||||
(0.0, 0.0, 0.0), (-1.0, 1.2246467991473532e-16, 0), (-0.8660254037844388, -0.4999999999999997, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (-0.8660254037844388, -0.4999999999999997, 0), (-0.5000000000000004, -0.8660254037844384, 0),
|
(0.5000000000000001, 0.8660254037844386, 0),
|
||||||
(0.0, 0.0, 0.0), (-0.5000000000000004, -0.8660254037844384, 0), (-1.8369701987210297e-16, -1.0, 0),
|
(6.123233995736766e-17, 1.0, 0),
|
||||||
(0.0, 0.0, 0.0), (-1.8369701987210297e-16, -1.0, 0), (0.49999999999999933, -0.866025403784439, 0),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0.49999999999999933, -0.866025403784439, 0), (0.8660254037844384, -0.5000000000000004, 0),
|
(6.123233995736766e-17, 1.0, 0),
|
||||||
(0.0, 0.0, 0.0), (0.8660254037844384, -0.5000000000000004, 0), (1.0, 0.0, 0),
|
(-0.4999999999999998, 0.8660254037844387, 0),
|
||||||
(0.0, 0.0, 0.0), (0, 1.0, 0.0), (0, 0.8660254037844387, 0.49999999999999994),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0, 0.8660254037844387, 0.49999999999999994), (0, 0.5000000000000001, 0.8660254037844386),
|
(-0.4999999999999998, 0.8660254037844387, 0),
|
||||||
(0.0, 0.0, 0.0), (0, 0.5000000000000001, 0.8660254037844386), (0, 6.123233995736766e-17, 1.0),
|
(-0.8660254037844385, 0.5000000000000003, 0),
|
||||||
(0.0, 0.0, 0.0), (0, 6.123233995736766e-17, 1.0), (0, -0.4999999999999998, 0.8660254037844387),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0, -0.4999999999999998, 0.8660254037844387), (0, -0.8660254037844385, 0.5000000000000003),
|
(-0.8660254037844385, 0.5000000000000003, 0),
|
||||||
(0.0, 0.0, 0.0), (0, -0.8660254037844385, 0.5000000000000003), (0, -1.0, 1.2246467991473532e-16),
|
(-1.0, 1.2246467991473532e-16, 0),
|
||||||
(0.0, 0.0, 0.0), (0, -1.0, 1.2246467991473532e-16), (0, -0.8660254037844388, -0.4999999999999997),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0, -0.8660254037844388, -0.4999999999999997), (0, -0.5000000000000004, -0.8660254037844384),
|
(-1.0, 1.2246467991473532e-16, 0),
|
||||||
(0.0, 0.0, 0.0), (0, -0.5000000000000004, -0.8660254037844384), (0, -1.8369701987210297e-16, -1.0),
|
(-0.8660254037844388, -0.4999999999999997, 0),
|
||||||
(0.0, 0.0, 0.0), (0, -1.8369701987210297e-16, -1.0), (0, 0.49999999999999933, -0.866025403784439),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0, 0.49999999999999933, -0.866025403784439), (0, 0.8660254037844384, -0.5000000000000004),
|
(-0.8660254037844388, -0.4999999999999997, 0),
|
||||||
(0.0, 0.0, 0.0), (0, 0.8660254037844384, -0.5000000000000004), (0, 1.0, 0.0),
|
(-0.5000000000000004, -0.8660254037844384, 0),
|
||||||
(0.0, 0.0, 0.0), (0.0, 0, 1.0), (0.49999999999999994, 0, 0.8660254037844387),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0.49999999999999994, 0, 0.8660254037844387), (0.8660254037844386, 0, 0.5000000000000001),
|
(-0.5000000000000004, -0.8660254037844384, 0),
|
||||||
(0.0, 0.0, 0.0), (0.8660254037844386, 0, 0.5000000000000001), (1.0, 0, 6.123233995736766e-17),
|
(-1.8369701987210297e-16, -1.0, 0),
|
||||||
(0.0, 0.0, 0.0), (1.0, 0, 6.123233995736766e-17), (0.8660254037844387, 0, -0.4999999999999998),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (0.8660254037844387, 0, -0.4999999999999998), (0.5000000000000003, 0, -0.8660254037844385),
|
(-1.8369701987210297e-16, -1.0, 0),
|
||||||
(0.0, 0.0, 0.0), (0.5000000000000003, 0, -0.8660254037844385), (1.2246467991473532e-16, 0, -1.0),
|
(0.49999999999999933, -0.866025403784439, 0),
|
||||||
(0.0, 0.0, 0.0), (1.2246467991473532e-16, 0, -1.0), (-0.4999999999999997, 0, -0.8660254037844388),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (-0.4999999999999997, 0, -0.8660254037844388), (-0.8660254037844384, 0, -0.5000000000000004),
|
(0.49999999999999933, -0.866025403784439, 0),
|
||||||
(0.0, 0.0, 0.0), (-0.8660254037844384, 0, -0.5000000000000004), (-1.0, 0, -1.8369701987210297e-16),
|
(0.8660254037844384, -0.5000000000000004, 0),
|
||||||
(0.0, 0.0, 0.0), (-1.0, 0, -1.8369701987210297e-16), (-0.866025403784439, 0, 0.49999999999999933),
|
(0.0, 0.0, 0.0),
|
||||||
(0.0, 0.0, 0.0), (-0.866025403784439, 0, 0.49999999999999933), (-0.5000000000000004, 0, 0.8660254037844384),
|
(0.8660254037844384, -0.5000000000000004, 0),
|
||||||
(0.0, 0.0, 0.0), (-0.5000000000000004, 0, 0.8660254037844384), (0.0, 0, 1.0),
|
(1.0, 0.0, 0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, 1.0, 0.0),
|
||||||
|
(0, 0.8660254037844387, 0.49999999999999994),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, 0.8660254037844387, 0.49999999999999994),
|
||||||
|
(0, 0.5000000000000001, 0.8660254037844386),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, 0.5000000000000001, 0.8660254037844386),
|
||||||
|
(0, 6.123233995736766e-17, 1.0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, 6.123233995736766e-17, 1.0),
|
||||||
|
(0, -0.4999999999999998, 0.8660254037844387),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, -0.4999999999999998, 0.8660254037844387),
|
||||||
|
(0, -0.8660254037844385, 0.5000000000000003),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, -0.8660254037844385, 0.5000000000000003),
|
||||||
|
(0, -1.0, 1.2246467991473532e-16),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, -1.0, 1.2246467991473532e-16),
|
||||||
|
(0, -0.8660254037844388, -0.4999999999999997),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, -0.8660254037844388, -0.4999999999999997),
|
||||||
|
(0, -0.5000000000000004, -0.8660254037844384),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, -0.5000000000000004, -0.8660254037844384),
|
||||||
|
(0, -1.8369701987210297e-16, -1.0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, -1.8369701987210297e-16, -1.0),
|
||||||
|
(0, 0.49999999999999933, -0.866025403784439),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, 0.49999999999999933, -0.866025403784439),
|
||||||
|
(0, 0.8660254037844384, -0.5000000000000004),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0, 0.8660254037844384, -0.5000000000000004),
|
||||||
|
(0, 1.0, 0.0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0.0, 0, 1.0),
|
||||||
|
(0.49999999999999994, 0, 0.8660254037844387),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0.49999999999999994, 0, 0.8660254037844387),
|
||||||
|
(0.8660254037844386, 0, 0.5000000000000001),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0.8660254037844386, 0, 0.5000000000000001),
|
||||||
|
(1.0, 0, 6.123233995736766e-17),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(1.0, 0, 6.123233995736766e-17),
|
||||||
|
(0.8660254037844387, 0, -0.4999999999999998),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0.8660254037844387, 0, -0.4999999999999998),
|
||||||
|
(0.5000000000000003, 0, -0.8660254037844385),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(0.5000000000000003, 0, -0.8660254037844385),
|
||||||
|
(1.2246467991473532e-16, 0, -1.0),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(1.2246467991473532e-16, 0, -1.0),
|
||||||
|
(-0.4999999999999997, 0, -0.8660254037844388),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.4999999999999997, 0, -0.8660254037844388),
|
||||||
|
(-0.8660254037844384, 0, -0.5000000000000004),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.8660254037844384, 0, -0.5000000000000004),
|
||||||
|
(-1.0, 0, -1.8369701987210297e-16),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-1.0, 0, -1.8369701987210297e-16),
|
||||||
|
(-0.866025403784439, 0, 0.49999999999999933),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.866025403784439, 0, 0.49999999999999933),
|
||||||
|
(-0.5000000000000004, 0, 0.8660254037844384),
|
||||||
|
(0.0, 0.0, 0.0),
|
||||||
|
(-0.5000000000000004, 0, 0.8660254037844384),
|
||||||
|
(0.0, 0, 1.0),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CustomGizmo():
|
class CustomGizmo:
|
||||||
# FIXME: highliting/selection doesnt work
|
# FIXME: highliting/selection doesnt work
|
||||||
def draw_very_custom_shape(self, ctx, custom_shape, select_id=None):
|
def draw_very_custom_shape(self, ctx, custom_shape, select_id=None):
|
||||||
# similar to draw_custom_shape
|
# similar to draw_custom_shape
|
||||||
@@ -127,7 +245,7 @@ class CustomGizmo():
|
|||||||
color = (*self.color_highlight, self.alpha_highlight)
|
color = (*self.color_highlight, self.alpha_highlight)
|
||||||
else:
|
else:
|
||||||
color = (*self.color, self.alpha)
|
color = (*self.color, self.alpha)
|
||||||
shader.uniform_float('color', color)
|
shader.uniform_float("color", color)
|
||||||
shape.glenable()
|
shape.glenable()
|
||||||
|
|
||||||
shape.uniform_region(ctx)
|
shape.uniform_region(ctx)
|
||||||
@@ -139,31 +257,32 @@ class CustomGizmo():
|
|||||||
bgl.glDisable(bgl.GL_BLEND)
|
bgl.glDisable(bgl.GL_BLEND)
|
||||||
|
|
||||||
|
|
||||||
class OffsetHandle():
|
class OffsetHandle:
|
||||||
"""Handling mouse to offset gizmo from base along Z axis"""
|
"""Handling mouse to offset gizmo from base along Z axis"""
|
||||||
|
|
||||||
# FIXME: works a bit weird for rotated objects
|
# FIXME: works a bit weird for rotated objects
|
||||||
|
|
||||||
def invoke(self, ctx, event):
|
def invoke(self, ctx, event):
|
||||||
self.init_value = self.target_get_value('offset') / self.scale_value
|
self.init_value = self.target_get_value("offset") / self.scale_value
|
||||||
coordz = self.project_mouse(ctx, event)
|
coordz = self.project_mouse(ctx, event)
|
||||||
if coordz is None:
|
if coordz is None:
|
||||||
return {'CANCELLED'}
|
return {"CANCELLED"}
|
||||||
self.init_coordz = coordz
|
self.init_coordz = coordz
|
||||||
return {'RUNNING_MODAL'}
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
def modal(self, ctx, event, tweak):
|
def modal(self, ctx, event, tweak):
|
||||||
coordz = self.project_mouse(ctx, event)
|
coordz = self.project_mouse(ctx, event)
|
||||||
if coordz is None:
|
if coordz is None:
|
||||||
return {'CANCELLED'}
|
return {"CANCELLED"}
|
||||||
delta = coordz - self.init_coordz
|
delta = coordz - self.init_coordz
|
||||||
if 'PRECISE' in tweak:
|
if "PRECISE" in tweak:
|
||||||
delta /= 10.0
|
delta /= 10.0
|
||||||
value = max(0, self.init_value + delta)
|
value = max(0, self.init_value + delta)
|
||||||
value *= self.scale_value
|
value *= self.scale_value
|
||||||
# ctx.area.header_text_set(f"coords: {self.init_coordz} - {coordz}, delta: {delta}, value: {value}")
|
# ctx.area.header_text_set(f"coords: {self.init_coordz} - {coordz}, delta: {delta}, value: {value}")
|
||||||
ctx.area.header_text_set(f"Depth: {value}")
|
ctx.area.header_text_set(f"Depth: {value}")
|
||||||
self.target_set_value('offset', value)
|
self.target_set_value("offset", value)
|
||||||
return {'RUNNING_MODAL'}
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
def project_mouse(self, ctx, event):
|
def project_mouse(self, ctx, event):
|
||||||
"""Projecting mouse coords to local axis Z"""
|
"""Projecting mouse coords to local axis Z"""
|
||||||
@@ -189,30 +308,29 @@ class OffsetHandle():
|
|||||||
|
|
||||||
def exit(self, ctx, cancel):
|
def exit(self, ctx, cancel):
|
||||||
if cancel:
|
if cancel:
|
||||||
self.target_set_value('offset', self.init_value)
|
self.target_set_value("offset", self.init_value)
|
||||||
else:
|
else:
|
||||||
self.group.update(ctx)
|
self.group.update(ctx)
|
||||||
|
|
||||||
|
|
||||||
class UglyDotGizmo(OffsetHandle, types.Gizmo):
|
class UglyDotGizmo(OffsetHandle, types.Gizmo):
|
||||||
"""three orthogonal circles"""
|
"""three orthogonal circles"""
|
||||||
|
|
||||||
bl_idname = "BIM_GT_uglydot_3d"
|
bl_idname = "BIM_GT_uglydot_3d"
|
||||||
bl_target_properties = (
|
bl_target_properties = ({"id": "offset", "type": "FLOAT", "array_length": 1},)
|
||||||
{'id': 'offset', 'type': 'FLOAT', 'array_length': 1},
|
|
||||||
)
|
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
'scale_value',
|
"scale_value",
|
||||||
'custom_shape',
|
"custom_shape",
|
||||||
'init_value',
|
"init_value",
|
||||||
'init_coordz',
|
"init_coordz",
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.custom_shape = self.new_custom_shape(type='TRIS', verts=X3DISC)
|
self.custom_shape = self.new_custom_shape(type="TRIS", verts=X3DISC)
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
offset = self.target_get_value('offset') / self.scale_value
|
offset = self.target_get_value("offset") / self.scale_value
|
||||||
self.matrix_offset.col[3][2] = offset # z-shift
|
self.matrix_offset.col[3][2] = offset # z-shift
|
||||||
|
|
||||||
def draw(self, ctx):
|
def draw(self, ctx):
|
||||||
@@ -226,15 +344,14 @@ class UglyDotGizmo(OffsetHandle, types.Gizmo):
|
|||||||
|
|
||||||
class DotGizmo(CustomGizmo, OffsetHandle, types.Gizmo):
|
class DotGizmo(CustomGizmo, OffsetHandle, types.Gizmo):
|
||||||
"""Single dot viewport-aligned"""
|
"""Single dot viewport-aligned"""
|
||||||
|
|
||||||
# FIXME: make it selectable
|
# FIXME: make it selectable
|
||||||
bl_idname = "BIM_GT_dot_2d"
|
bl_idname = "BIM_GT_dot_2d"
|
||||||
bl_target_properties = (
|
bl_target_properties = ({"id": "offset", "type": "FLOAT", "array_length": 1},)
|
||||||
{'id': 'offset', 'type': 'FLOAT', 'array_length': 1},
|
|
||||||
)
|
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
'scale_value',
|
"scale_value",
|
||||||
'custom_shape',
|
"custom_shape",
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
@@ -243,7 +360,7 @@ class DotGizmo(CustomGizmo, OffsetHandle, types.Gizmo):
|
|||||||
self.use_draw_scale = False
|
self.use_draw_scale = False
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
offset = self.target_get_value('offset') / self.scale_value
|
offset = self.target_get_value("offset") / self.scale_value
|
||||||
self.matrix_offset.col[3][2] = offset # z-shifted
|
self.matrix_offset.col[3][2] = offset # z-shifted
|
||||||
|
|
||||||
def draw(self, ctx):
|
def draw(self, ctx):
|
||||||
@@ -265,15 +382,11 @@ class ExtrusionGuidesGizmo(CustomGizmo, types.Gizmo):
|
|||||||
Noninteractive gizmo to indicate extrusion depth and planes.
|
Noninteractive gizmo to indicate extrusion depth and planes.
|
||||||
Draws main segment and orthogonal cross at endpoints.
|
Draws main segment and orthogonal cross at endpoints.
|
||||||
"""
|
"""
|
||||||
bl_idname = "BIM_GT_extrusion_guides"
|
|
||||||
bl_target_properties = (
|
|
||||||
{'id': 'depth', 'type': 'FLOAT', 'array_length': 1},
|
|
||||||
)
|
|
||||||
|
|
||||||
__slots__ = (
|
bl_idname = "BIM_GT_extrusion_guides"
|
||||||
'scale_value',
|
bl_target_properties = ({"id": "depth", "type": "FLOAT", "array_length": 1},)
|
||||||
'custom_shape'
|
|
||||||
)
|
__slots__ = ("scale_value", "custom_shape")
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
shader = ExtrusionGuidesShader()
|
shader = ExtrusionGuidesShader()
|
||||||
@@ -281,7 +394,7 @@ class ExtrusionGuidesGizmo(CustomGizmo, types.Gizmo):
|
|||||||
self.use_draw_scale = False
|
self.use_draw_scale = False
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
depth = self.target_get_value('depth') / self.scale_value
|
depth = self.target_get_value("depth") / self.scale_value
|
||||||
self.matrix_offset.col[2][2] = depth # z-scaled
|
self.matrix_offset.col[2][2] = depth # z-scaled
|
||||||
|
|
||||||
def draw(self, ctx):
|
def draw(self, ctx):
|
||||||
@@ -291,25 +404,22 @@ class ExtrusionGuidesGizmo(CustomGizmo, types.Gizmo):
|
|||||||
|
|
||||||
class DimensionLabelGizmo(types.Gizmo):
|
class DimensionLabelGizmo(types.Gizmo):
|
||||||
"""Text label for a dimension"""
|
"""Text label for a dimension"""
|
||||||
|
|
||||||
# does not work properly, fonts are totally screwed up
|
# does not work properly, fonts are totally screwed up
|
||||||
|
|
||||||
bl_idname = "BIM_GT_dimension_label"
|
bl_idname = "BIM_GT_dimension_label"
|
||||||
bl_target_properties = (
|
bl_target_properties = ({"id": "value", "type": "FLOAT", "array_length": 1},)
|
||||||
{'id': 'value', 'type': 'FLOAT', 'array_length': 1},
|
|
||||||
)
|
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = "text_label"
|
||||||
'text_label'
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def refresh(self, ctx):
|
def refresh(self, ctx):
|
||||||
value = self.target_get_value('value')
|
value = self.target_get_value("value")
|
||||||
self.matrix_offset.col[3][2] = value * .5
|
self.matrix_offset.col[3][2] = value * 0.5
|
||||||
unit_system = ctx.scene.unit_settings.system
|
unit_system = ctx.scene.unit_settings.system
|
||||||
self.text_label = bpy.utils.units.to_string(unit_system, 'LENGTH', value, 3, split_unit=False)
|
self.text_label = bpy.utils.units.to_string(unit_system, "LENGTH", value, 3, split_unit=False)
|
||||||
|
|
||||||
def draw(self, ctx):
|
def draw(self, ctx):
|
||||||
self.refresh(ctx)
|
self.refresh(ctx)
|
||||||
@@ -337,41 +447,44 @@ class DimensionLabelGizmo(types.Gizmo):
|
|||||||
class ExtrusionWidget(types.GizmoGroup):
|
class ExtrusionWidget(types.GizmoGroup):
|
||||||
bl_idname = "bim.extrusion_widget"
|
bl_idname = "bim.extrusion_widget"
|
||||||
bl_label = "Extrusion Gizmos"
|
bl_label = "Extrusion Gizmos"
|
||||||
bl_space_type = 'VIEW_3D'
|
bl_space_type = "VIEW_3D"
|
||||||
bl_region_type = 'WINDOW'
|
bl_region_type = "WINDOW"
|
||||||
bl_options = {'3D', 'PERSISTENT', 'SHOW_MODAL_ALL'}
|
bl_options = {"3D", "PERSISTENT", "SHOW_MODAL_ALL"}
|
||||||
|
|
||||||
# FIXME: use proper scale from ifc value to blender units
|
# FIXME: use proper scale from ifc value to blender units
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, ctx):
|
def poll(cls, ctx):
|
||||||
obj = ctx.object
|
obj = ctx.object
|
||||||
return (obj and obj.type == 'MESH'
|
return (
|
||||||
and obj.data.BIMMeshProperties.ifc_parameters.get('IfcExtrudedAreaSolid/Depth') is not None)
|
obj
|
||||||
|
and obj.type == "MESH"
|
||||||
|
and obj.data.BIMMeshProperties.ifc_parameters.get("IfcExtrudedAreaSolid/Depth") is not None
|
||||||
|
)
|
||||||
|
|
||||||
def setup(self, ctx):
|
def setup(self, ctx):
|
||||||
target = ctx.object
|
target = ctx.object
|
||||||
prop = target.data.BIMMeshProperties.ifc_parameters.get('IfcExtrudedAreaSolid/Depth')
|
prop = target.data.BIMMeshProperties.ifc_parameters.get("IfcExtrudedAreaSolid/Depth")
|
||||||
|
|
||||||
basis = target.matrix_world.normalized()
|
basis = target.matrix_world.normalized()
|
||||||
theme = ctx.preferences.themes[0].user_interface
|
theme = ctx.preferences.themes[0].user_interface
|
||||||
|
|
||||||
gz = self.handle = self.gizmos.new('BIM_GT_uglydot_3d')
|
gz = self.handle = self.gizmos.new("BIM_GT_uglydot_3d")
|
||||||
gz.matrix_basis = basis
|
gz.matrix_basis = basis
|
||||||
gz.scale_basis = 0.1
|
gz.scale_basis = 0.1
|
||||||
gz.color = gz.color_highlight = tuple(theme.gizmo_primary)
|
gz.color = gz.color_highlight = tuple(theme.gizmo_primary)
|
||||||
gz.alpha = 0.5
|
gz.alpha = 0.5
|
||||||
gz.alpha_highlight = 1.0
|
gz.alpha_highlight = 1.0
|
||||||
gz.use_draw_modal = True
|
gz.use_draw_modal = True
|
||||||
gz.target_set_prop('offset', prop, 'value')
|
gz.target_set_prop("offset", prop, "value")
|
||||||
gz.scale_value = 1000
|
gz.scale_value = 1000
|
||||||
|
|
||||||
gz = self.guides = self.gizmos.new('BIM_GT_extrusion_guides')
|
gz = self.guides = self.gizmos.new("BIM_GT_extrusion_guides")
|
||||||
gz.matrix_basis = basis
|
gz.matrix_basis = basis
|
||||||
gz.color = gz.color_highlight = tuple(theme.gizmo_secondary)
|
gz.color = gz.color_highlight = tuple(theme.gizmo_secondary)
|
||||||
gz.alpha = gz.alpha_highlight = 0.5
|
gz.alpha = gz.alpha_highlight = 0.5
|
||||||
gz.use_draw_modal = True
|
gz.use_draw_modal = True
|
||||||
gz.target_set_prop('depth', prop, 'value')
|
gz.target_set_prop("depth", prop, "value")
|
||||||
gz.scale_value = 1000
|
gz.scale_value = 1000
|
||||||
|
|
||||||
# gz = self.label = self.gizmos.new('GIZMO_GT_dimension_label')
|
# gz = self.label = self.gizmos.new('GIZMO_GT_dimension_label')
|
||||||
@@ -395,6 +508,6 @@ class ExtrusionWidget(types.GizmoGroup):
|
|||||||
# need to retrieve and rebind them again
|
# need to retrieve and rebind them again
|
||||||
bpy.ops.bim.get_representation_ifc_parameters()
|
bpy.ops.bim.get_representation_ifc_parameters()
|
||||||
target = ctx.object
|
target = ctx.object
|
||||||
prop = target.data.BIMMeshProperties.ifc_parameters.get('IfcExtrudedAreaSolid/Depth')
|
prop = target.data.BIMMeshProperties.ifc_parameters.get("IfcExtrudedAreaSolid/Depth")
|
||||||
self.handle.target_set_prop('offset', prop, 'value')
|
self.handle.target_set_prop("offset", prop, "value")
|
||||||
self.guides.target_set_prop('depth', prop, 'value')
|
self.guides.target_set_prop("depth", prop, "value")
|
||||||
@@ -10,3 +10,23 @@ def toggleDecorationsOnLoad(*args):
|
|||||||
decoration.DecorationsHandler.install(bpy.context)
|
decoration.DecorationsHandler.install(bpy.context)
|
||||||
else:
|
else:
|
||||||
decoration.DecorationsHandler.uninstall()
|
decoration.DecorationsHandler.uninstall()
|
||||||
|
|
||||||
|
|
||||||
|
@persistent
|
||||||
|
def depsgraph_update_pre_handler(scene):
|
||||||
|
set_active_camera_resolution(scene)
|
||||||
|
|
||||||
|
|
||||||
|
def set_active_camera_resolution(scene):
|
||||||
|
if not scene.camera or "/" not in scene.camera.name or not scene.DocProperties.drawings:
|
||||||
|
return
|
||||||
|
if (
|
||||||
|
scene.render.resolution_x != scene.camera.data.BIMCameraProperties.raster_x
|
||||||
|
or scene.render.resolution_y != scene.camera.data.BIMCameraProperties.raster_y
|
||||||
|
):
|
||||||
|
scene.render.resolution_x = scene.camera.data.BIMCameraProperties.raster_x
|
||||||
|
scene.render.resolution_y = scene.camera.data.BIMCameraProperties.raster_y
|
||||||
|
current_drawing = scene.DocProperties.drawings[scene.DocProperties.current_drawing_index]
|
||||||
|
if scene.camera != current_drawing.camera:
|
||||||
|
scene.DocProperties.current_drawing_index = scene.DocProperties.drawings.find(scene.camera.name.split("/")[1])
|
||||||
|
bpy.ops.bim.activate_view(drawing_index=scene.DocProperties.current_drawing_index)
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
import os
|
import os
|
||||||
import bpy
|
import bpy
|
||||||
import json
|
import json
|
||||||
|
import bmesh
|
||||||
import subprocess
|
import subprocess
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
import ifcopenshell.util.selector
|
||||||
import ifcopenshell.util.representation
|
import ifcopenshell.util.representation
|
||||||
import blenderbim.bim.module.drawing.svgwriter as svgwriter
|
import blenderbim.bim.module.drawing.svgwriter as svgwriter
|
||||||
import blenderbim.bim.module.drawing.annotation as annotation
|
import blenderbim.bim.module.drawing.annotation as annotation
|
||||||
|
import blenderbim.bim.module.drawing.cut_ifc as cut_ifc # TODO: deprecate
|
||||||
|
import blenderbim.bim.module.drawing.sheeter as sheeter
|
||||||
|
import blenderbim.bim.module.drawing.scheduler as scheduler
|
||||||
from mathutils import Vector, Matrix, Euler, geometry
|
from mathutils import Vector, Matrix, Euler, geometry
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from ifcopenshell.api.group.data import Data as GroupData
|
from ifcopenshell.api.group.data import Data as GroupData
|
||||||
@@ -245,3 +250,955 @@ class AddAnnotation(bpy.types.Operator):
|
|||||||
obj.select_set(True)
|
obj.select_set(True)
|
||||||
bpy.ops.object.mode_set(mode="EDIT")
|
bpy.ops.object.mode_set(mode="EDIT")
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CutSection(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.cut_section"
|
||||||
|
bl_label = "Cut Section"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
self.file = ifc.IfcStore.get_file()
|
||||||
|
camera = bpy.context.scene.camera
|
||||||
|
if not (camera.type == "CAMERA" and camera.data.type == "ORTHO"):
|
||||||
|
return {"FINISHED"}
|
||||||
|
if not bpy.context.scene.DocProperties.ifc_files and bpy.context.scene.BIMProperties.ifc_file:
|
||||||
|
new = bpy.context.scene.DocProperties.ifc_files.add()
|
||||||
|
new.name = bpy.context.scene.BIMProperties.ifc_file
|
||||||
|
bpy.ops.bim.activate_view(
|
||||||
|
drawing_index=bpy.context.scene.DocProperties.drawings.find(camera.name.split("/")[1])
|
||||||
|
)
|
||||||
|
drawing_style = bpy.context.scene.DocProperties.drawing_styles[
|
||||||
|
camera.data.BIMCameraProperties.active_drawing_style_index
|
||||||
|
]
|
||||||
|
self.diagram_name = camera.name.split("/")[1]
|
||||||
|
bpy.context.scene.render.filepath = os.path.join(
|
||||||
|
bpy.context.scene.BIMProperties.data_dir, "diagrams", "{}.png".format(self.diagram_name)
|
||||||
|
)
|
||||||
|
self.create_raster(camera, drawing_style)
|
||||||
|
location = camera.location
|
||||||
|
render = bpy.context.scene.render
|
||||||
|
if self.is_landscape():
|
||||||
|
width = camera.data.ortho_scale
|
||||||
|
height = width / render.resolution_x * render.resolution_y
|
||||||
|
else:
|
||||||
|
height = camera.data.ortho_scale
|
||||||
|
width = height / render.resolution_y * render.resolution_x
|
||||||
|
depth = camera.data.clip_end
|
||||||
|
projection = camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
|
||||||
|
x_axis = camera.matrix_world.to_quaternion() @ Vector((1, 0, 0))
|
||||||
|
y_axis = camera.matrix_world.to_quaternion() @ Vector((0, -1, 0))
|
||||||
|
top_left_corner = location - (width / 2 * x_axis) - (height / 2 * y_axis)
|
||||||
|
ifc_cutter = cut_ifc.IfcCutter()
|
||||||
|
|
||||||
|
ifc_cutter.ifc_filenames = [i.name for i in bpy.context.scene.DocProperties.ifc_files]
|
||||||
|
ifc_cutter.data_dir = bpy.context.scene.BIMProperties.data_dir
|
||||||
|
ifc_cutter.vector_style = drawing_style.vector_style
|
||||||
|
ifc_cutter.diagram_name = self.diagram_name
|
||||||
|
ifc_cutter.background_image = bpy.context.scene.render.filepath
|
||||||
|
if camera.data.BIMCameraProperties.cut_objects == "CUSTOM":
|
||||||
|
ifc_cutter.cut_objects = camera.data.BIMCameraProperties.cut_objects_custom
|
||||||
|
else:
|
||||||
|
ifc_cutter.cut_objects = camera.data.BIMCameraProperties.cut_objects
|
||||||
|
ifc_cutter.leader_obj = None
|
||||||
|
ifc_cutter.stair_obj = None
|
||||||
|
ifc_cutter.dimension_objs = []
|
||||||
|
ifc_cutter.break_obj = None
|
||||||
|
ifc_cutter.equal_objs = []
|
||||||
|
ifc_cutter.hidden_objs = []
|
||||||
|
ifc_cutter.solid_objs = []
|
||||||
|
ifc_cutter.plan_level_obj = None
|
||||||
|
ifc_cutter.section_level_obj = None
|
||||||
|
ifc_cutter.grid_objs = []
|
||||||
|
ifc_cutter.text_objs = []
|
||||||
|
ifc_cutter.misc_objs = []
|
||||||
|
ifc_cutter.attributes = [a.name for a in drawing_style.attributes]
|
||||||
|
for obj in camera.users_collection[0].objects:
|
||||||
|
if "IfcGrid" in obj.name:
|
||||||
|
ifc_cutter.grid_objs.append(obj)
|
||||||
|
elif "IfcGroup" in obj.name and obj.type == "CAMERA":
|
||||||
|
ifc_cutter.camera_obj = obj
|
||||||
|
|
||||||
|
if "IfcAnnotation/" not in obj.name:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "Leader" in obj.name:
|
||||||
|
ifc_cutter.leader_obj = (obj, obj.data)
|
||||||
|
elif "Stair" in obj.name:
|
||||||
|
ifc_cutter.stair_obj = obj
|
||||||
|
elif "Equal" in obj.name:
|
||||||
|
ifc_cutter.equal_objs.append(obj)
|
||||||
|
elif "Dimension" in obj.name:
|
||||||
|
ifc_cutter.dimension_objs.append(obj)
|
||||||
|
elif "Break" in obj.name:
|
||||||
|
ifc_cutter.break_obj = obj
|
||||||
|
elif "Hidden" in obj.name:
|
||||||
|
ifc_cutter.hidden_objs.append((obj, obj.data))
|
||||||
|
elif "Solid" in obj.name:
|
||||||
|
ifc_cutter.solid_objs.append((obj, obj.data))
|
||||||
|
elif "Plan Level" in obj.name:
|
||||||
|
ifc_cutter.plan_level_obj = obj
|
||||||
|
elif "Section Level" in obj.name:
|
||||||
|
ifc_cutter.section_level_obj = obj
|
||||||
|
elif obj.type == "FONT":
|
||||||
|
ifc_cutter.text_objs.append(obj)
|
||||||
|
else:
|
||||||
|
ifc_cutter.misc_objs.append(obj)
|
||||||
|
|
||||||
|
ifc_cutter.section_box = {
|
||||||
|
"projection": tuple(projection),
|
||||||
|
"x_axis": tuple(x_axis),
|
||||||
|
"y_axis": tuple(y_axis),
|
||||||
|
"top_left_corner": tuple(top_left_corner),
|
||||||
|
"x": width,
|
||||||
|
"y": height,
|
||||||
|
"z": depth,
|
||||||
|
"shape": None,
|
||||||
|
"face": None,
|
||||||
|
}
|
||||||
|
ifc_cutter.cut_pickle_file = os.path.join(ifc_cutter.data_dir, "{}-cut.pickle".format(self.diagram_name))
|
||||||
|
ifc_cutter.text_pickle_file = os.path.join(ifc_cutter.data_dir, "{}-text.pickle".format(self.diagram_name))
|
||||||
|
ifc_cutter.metadata_pickle_file = os.path.join(
|
||||||
|
ifc_cutter.data_dir, "{}-metadata.pickle".format(self.diagram_name)
|
||||||
|
)
|
||||||
|
ifc_cutter.should_recut = bpy.context.scene.DocProperties.should_recut
|
||||||
|
ifc_cutter.should_recut_selected = bpy.context.scene.DocProperties.should_recut_selected
|
||||||
|
selected_global_ids = []
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if "Ifc" not in obj.name:
|
||||||
|
continue
|
||||||
|
for attribute in obj.BIMObjectProperties.attributes:
|
||||||
|
if attribute.name == "GlobalId":
|
||||||
|
selected_global_ids.append(attribute.string_value)
|
||||||
|
break
|
||||||
|
ifc_cutter.selected_global_ids = selected_global_ids
|
||||||
|
ifc_cutter.should_extract = bpy.context.scene.DocProperties.should_extract
|
||||||
|
svg_writer = svgwriter.SvgWriter(ifc_cutter)
|
||||||
|
if camera.data.BIMCameraProperties.diagram_scale == "CUSTOM":
|
||||||
|
human_scale, fraction = camera.data.BIMCameraProperties.custom_diagram_scale.split("|")
|
||||||
|
else:
|
||||||
|
human_scale, fraction = camera.data.BIMCameraProperties.diagram_scale.split("|")
|
||||||
|
numerator, denominator = fraction.split("/")
|
||||||
|
if camera.data.BIMCameraProperties.is_nts:
|
||||||
|
svg_writer.human_scale = "NTS"
|
||||||
|
else:
|
||||||
|
svg_writer.human_scale = human_scale
|
||||||
|
svg_writer.scale = float(numerator) / float(denominator)
|
||||||
|
ifc_cutter.cut()
|
||||||
|
svg_writer.write()
|
||||||
|
bpy.ops.bim.open_view(view=self.diagram_name)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def create_raster(self, camera, drawing_style):
|
||||||
|
if drawing_style.render_type == "NONE":
|
||||||
|
return
|
||||||
|
|
||||||
|
if drawing_style.render_type == "DEFAULT":
|
||||||
|
return bpy.ops.render.render(write_still=True)
|
||||||
|
|
||||||
|
previous_visibility = {}
|
||||||
|
for obj in camera.users_collection[0].objects:
|
||||||
|
previous_visibility[obj.name] = obj.hide_get()
|
||||||
|
obj.hide_set(True)
|
||||||
|
for obj in bpy.context.visible_objects:
|
||||||
|
if (
|
||||||
|
(not obj.data and not obj.instance_collection)
|
||||||
|
or isinstance(obj.data, bpy.types.Camera)
|
||||||
|
or "IfcGrid/" in obj.name
|
||||||
|
or "IfcGridAxis/" in obj.name
|
||||||
|
or "IfcOpeningElement/" in obj.name
|
||||||
|
or self.does_obj_have_target_view_representation(obj, camera)
|
||||||
|
):
|
||||||
|
previous_visibility[obj.name] = obj.hide_get()
|
||||||
|
obj.hide_set(True)
|
||||||
|
|
||||||
|
space = self.get_view_3d()
|
||||||
|
previous_shading = space.shading.type
|
||||||
|
previous_format = bpy.context.scene.render.image_settings.file_format
|
||||||
|
space.shading.type = "RENDERED"
|
||||||
|
bpy.context.scene.render.image_settings.file_format = "PNG"
|
||||||
|
bpy.ops.render.opengl(write_still=True)
|
||||||
|
space.shading.type = previous_shading
|
||||||
|
bpy.context.scene.render.image_settings.file_format = previous_format
|
||||||
|
|
||||||
|
for name, value in previous_visibility.items():
|
||||||
|
bpy.data.objects[name].hide_set(value)
|
||||||
|
|
||||||
|
def does_obj_have_target_view_representation(self, obj, camera):
|
||||||
|
if not obj.BIMObjectProperties.ifc_definition_id:
|
||||||
|
return False
|
||||||
|
element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||||
|
if not element.Representation:
|
||||||
|
return False
|
||||||
|
for representation in element.Representation.Representations:
|
||||||
|
if ifcopenshell.util.representation.is_representation_of_context(
|
||||||
|
representation, "Plan", "Annotation", camera.data.BIMCameraProperties.target_view
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_landscape(self):
|
||||||
|
return bpy.context.scene.render.resolution_x > bpy.context.scene.render.resolution_y
|
||||||
|
|
||||||
|
def get_view_3d(self):
|
||||||
|
for area in bpy.context.screen.areas:
|
||||||
|
if area.type != "VIEW_3D":
|
||||||
|
continue
|
||||||
|
for space in area.spaces:
|
||||||
|
if space.type != "VIEW_3D":
|
||||||
|
continue
|
||||||
|
return space
|
||||||
|
|
||||||
|
|
||||||
|
class AddSheet(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_sheet"
|
||||||
|
bl_label = "Add Sheet"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
new = bpy.context.scene.DocProperties.sheets.add()
|
||||||
|
new.name = "{} - SHEET".format(len(bpy.context.scene.DocProperties.sheets))
|
||||||
|
sheet_builder = sheeter.SheetBuilder()
|
||||||
|
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
|
||||||
|
sheet_builder.create(new.name, bpy.context.scene.DocProperties.titleblock)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class OpenSheet(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.open_sheet"
|
||||||
|
bl_label = "Open Sheet"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
open_with_user_command(
|
||||||
|
bpy.context.preferences.addons["blenderbim"].preferences.svg_command,
|
||||||
|
os.path.join(
|
||||||
|
bpy.context.scene.BIMProperties.data_dir, "sheets", props.sheets[props.active_sheet_index].name + ".svg"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddDrawingToSheet(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_drawing_to_sheet"
|
||||||
|
bl_label = "Add Drawing To Sheet"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
sheet_builder = sheeter.SheetBuilder()
|
||||||
|
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
|
||||||
|
try:
|
||||||
|
sheet_builder.add_drawing(
|
||||||
|
props.drawings[props.active_drawing_index].name, props.sheets[props.active_sheet_index].name
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
self.report({"ERROR"}, "Drawings need to be created before being added to a sheet")
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CreateSheets(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.create_sheets"
|
||||||
|
bl_label = "Create Sheets"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
name = props.sheets[props.active_sheet_index].name
|
||||||
|
sheet_builder = sheeter.SheetBuilder()
|
||||||
|
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
|
||||||
|
sheet_builder.build(name)
|
||||||
|
|
||||||
|
svg2pdf_command = bpy.context.preferences.addons["blenderbim"].preferences.svg2pdf_command
|
||||||
|
svg2dxf_command = bpy.context.preferences.addons["blenderbim"].preferences.svg2dxf_command
|
||||||
|
|
||||||
|
if svg2pdf_command:
|
||||||
|
path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "build", name)
|
||||||
|
svg = os.path.join(path, name + ".svg")
|
||||||
|
pdf = os.path.join(path, name + ".pdf")
|
||||||
|
# With great power comes great responsibility. Example:
|
||||||
|
# [['inkscape', svg, '-o', pdf]]
|
||||||
|
commands = eval(svg2pdf_command)
|
||||||
|
for command in commands:
|
||||||
|
subprocess.run(command)
|
||||||
|
|
||||||
|
if svg2dxf_command:
|
||||||
|
path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "build", name)
|
||||||
|
svg = os.path.join(path, name + ".svg")
|
||||||
|
eps = os.path.join(path, name + ".eps")
|
||||||
|
dxf = os.path.join(path, name + ".dxf")
|
||||||
|
base = os.path.join(path, name)
|
||||||
|
# With great power comes great responsibility. Example:
|
||||||
|
# [['inkscape', svg, '-o', eps], ['pstoedit', '-dt', '-f', 'dxf:-polyaslines -mm', eps, dxf, '-psarg', '-dNOSAFER']]
|
||||||
|
commands = eval(svg2dxf_command)
|
||||||
|
for command in commands:
|
||||||
|
subprocess.run(command)
|
||||||
|
|
||||||
|
if svg2pdf_command:
|
||||||
|
open_with_user_command(bpy.context.preferences.addons["blenderbim"].preferences.pdf_command, pdf)
|
||||||
|
else:
|
||||||
|
open_with_user_command(
|
||||||
|
bpy.context.preferences.addons["blenderbim"].preferences.svg_command,
|
||||||
|
os.path.join(bpy.context.scene.BIMProperties.data_dir, "build", name, name + ".svg"),
|
||||||
|
)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class OpenView(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.open_view"
|
||||||
|
bl_label = "Open View"
|
||||||
|
view: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
open_with_user_command(
|
||||||
|
bpy.context.preferences.addons["blenderbim"].preferences.svg_command,
|
||||||
|
os.path.join(bpy.context.scene.BIMProperties.data_dir, "diagrams", self.view + ".svg"),
|
||||||
|
)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class OpenViewCamera(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.open_view_camera"
|
||||||
|
bl_label = "Open View Camera"
|
||||||
|
view_name: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
new_drawing_index = bpy.context.scene.DocProperties.drawings.find(self.view_name)
|
||||||
|
bpy.context.scene.DocProperties.active_drawing_index = new_drawing_index
|
||||||
|
drawing = bpy.context.scene.DocProperties.drawings[new_drawing_index]
|
||||||
|
bpy.context.view_layer.objects.active = drawing.camera
|
||||||
|
bpy.ops.object.select_all(action="DESELECT")
|
||||||
|
drawing.camera.select_set(True)
|
||||||
|
for area in bpy.context.screen.areas:
|
||||||
|
if area.ui_type == "PROPERTIES":
|
||||||
|
for space in area.spaces:
|
||||||
|
space.context = "DATA"
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class ActivateView(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.activate_view"
|
||||||
|
bl_label = "Activate View"
|
||||||
|
drawing_index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
camera = bpy.context.scene.DocProperties.drawings[self.drawing_index].camera
|
||||||
|
if not camera:
|
||||||
|
return {"FINISHED"}
|
||||||
|
bpy.context.scene.camera = camera
|
||||||
|
area = next(area for area in bpy.context.screen.areas if area.type == "VIEW_3D")
|
||||||
|
area.spaces[0].region_3d.view_perspective = "CAMERA"
|
||||||
|
views_collection = bpy.data.collections.get("Views")
|
||||||
|
for collection in views_collection.children:
|
||||||
|
# We assume the project collection is at the top level
|
||||||
|
for project_collection in bpy.context.view_layer.layer_collection.children:
|
||||||
|
# We assume a convention that the 'Views' collection is directly
|
||||||
|
# in the project collection
|
||||||
|
if (
|
||||||
|
"Views" in project_collection.children
|
||||||
|
and collection.name in project_collection.children["Views"].children
|
||||||
|
):
|
||||||
|
project_collection.children["Views"].children[collection.name].hide_viewport = True
|
||||||
|
bpy.data.collections.get(collection.name).hide_render = True
|
||||||
|
bpy.context.view_layer.layer_collection.children["Views"].children[
|
||||||
|
camera.users_collection[0].name
|
||||||
|
].hide_viewport = False
|
||||||
|
bpy.data.collections.get(camera.users_collection[0].name).hide_render = False
|
||||||
|
bpy.ops.bim.activate_drawing_style()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class SelectDocIfcFile(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.select_doc_ifc_file"
|
||||||
|
bl_label = "Select Documentation IFC File"
|
||||||
|
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
bpy.context.scene.DocProperties.ifc_files[self.index].name = self.filepath
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
context.window_manager.fileselect_add(self)
|
||||||
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateReferences(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.generate_references"
|
||||||
|
bl_label = "Generate References"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
self.camera = bpy.context.scene.camera
|
||||||
|
self.filter_potential_references()
|
||||||
|
if self.camera.data.BIMCameraProperties.target_view == "PLAN_VIEW":
|
||||||
|
self.generate_grids()
|
||||||
|
if self.camera.data.BIMCameraProperties.target_view == "ELEVATION_VIEW":
|
||||||
|
self.generate_grids()
|
||||||
|
self.generate_levels()
|
||||||
|
if self.camera.data.BIMCameraProperties.target_view == "SECTION_VIEW":
|
||||||
|
self.generate_grids()
|
||||||
|
self.generate_levels()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def filter_potential_references(self):
|
||||||
|
for name in ["grids", "levels"]:
|
||||||
|
setattr(self, name, [])
|
||||||
|
for obj in bpy.data.objects:
|
||||||
|
if "IfcGridAxis/" in obj.name:
|
||||||
|
self.grids.append(obj)
|
||||||
|
if "IfcBuildingStorey/" in obj.name:
|
||||||
|
self.levels.append(obj)
|
||||||
|
|
||||||
|
def generate_grids(self):
|
||||||
|
# TODO
|
||||||
|
pass
|
||||||
|
|
||||||
|
def generate_levels(self):
|
||||||
|
if self.camera.data.BIMCameraProperties.raster_x > self.camera.data.BIMCameraProperties.raster_y:
|
||||||
|
width = self.camera.data.ortho_scale
|
||||||
|
height = (
|
||||||
|
width / self.camera.data.BIMCameraProperties.raster_x * self.camera.data.BIMCameraProperties.raster_y
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
height = self.camera.data.ortho_scale
|
||||||
|
width = (
|
||||||
|
height / self.camera.data.BIMCameraProperties.raster_y * self.camera.data.BIMCameraProperties.raster_x
|
||||||
|
)
|
||||||
|
level_obj = annotation.Annotator.get_annotation_obj("Section Level", "curve")
|
||||||
|
|
||||||
|
width_in_mm = width * 1000
|
||||||
|
if self.camera.data.BIMCameraProperties.diagram_scale == "CUSTOM":
|
||||||
|
human_scale, fraction = self.camera.data.BIMCameraProperties.custom_diagram_scale.split("|")
|
||||||
|
else:
|
||||||
|
human_scale, fraction = self.camera.data.BIMCameraProperties.diagram_scale.split("|")
|
||||||
|
numerator, denominator = fraction.split("/")
|
||||||
|
scale = float(numerator) / float(denominator)
|
||||||
|
real_world_width_in_mm = width_in_mm * scale
|
||||||
|
offset_in_mm = 20
|
||||||
|
offset_percentage = offset_in_mm / real_world_width_in_mm
|
||||||
|
|
||||||
|
for obj in self.levels:
|
||||||
|
projection = self.project_point_onto_camera(obj.location)
|
||||||
|
co1 = self.camera.matrix_world @ Vector((width / 2 - (offset_percentage * width), projection[1], -1))
|
||||||
|
co2 = self.camera.matrix_world @ Vector((-(width / 2), projection[1], -1))
|
||||||
|
annotation.Annotator.add_line_to_annotation(level_obj, co1, co2)
|
||||||
|
|
||||||
|
def project_point_onto_camera(self, point):
|
||||||
|
projection = self.camera.matrix_world.to_quaternion() @ Vector((0, 0, -1))
|
||||||
|
return self.camera.matrix_world.inverted() @ geometry.intersect_line_plane(
|
||||||
|
point.xyz, point.xyz - projection, self.camera.location, projection
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ResizeText(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.resize_text"
|
||||||
|
bl_label = "Resize Text"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
for obj in bpy.context.scene.camera.users_collection[0].objects:
|
||||||
|
if isinstance(obj.data, bpy.types.TextCurve):
|
||||||
|
annotation.Annotator.resize_text(obj)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddVariable(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_variable"
|
||||||
|
bl_label = "Add Variable"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
bpy.context.active_object.data.BIMTextProperties.variables.add()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveVariable(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.remove_variable"
|
||||||
|
bl_label = "Remove Variable"
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
bpy.context.active_object.data.BIMTextProperties.variables.remove(self.index)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class PropagateTextData(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.propagate_text_data"
|
||||||
|
bl_label = "Propagate Text Data"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
source = bpy.context.active_object
|
||||||
|
for obj in bpy.context.selected_objects:
|
||||||
|
if obj == source:
|
||||||
|
continue
|
||||||
|
obj.data.body = source.data.body
|
||||||
|
obj.data.align_x = source.data.align_x
|
||||||
|
obj.data.align_y = source.data.align_y
|
||||||
|
obj.data.BIMTextProperties.font_size = source.data.BIMTextProperties.font_size
|
||||||
|
obj.data.BIMTextProperties.symbol = source.data.BIMTextProperties.symbol
|
||||||
|
while len(obj.data.BIMTextProperties.variables) > 0:
|
||||||
|
obj.data.BIMTextProperties.variables.remove(0)
|
||||||
|
for variable in source.data.BIMTextProperties.variables:
|
||||||
|
new_variable = obj.data.BIMTextProperties.variables.add()
|
||||||
|
new_variable.name = variable.name
|
||||||
|
new_variable.prop_key = variable.prop_key
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveDrawing(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.remove_drawing"
|
||||||
|
bl_label = "Remove Drawing"
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
camera = props.drawings[self.index].camera
|
||||||
|
collection = camera.users_collection[0]
|
||||||
|
for obj in collection.objects:
|
||||||
|
bpy.data.objects.remove(obj)
|
||||||
|
bpy.data.collections.remove(collection, do_unlink=True)
|
||||||
|
props.drawings.remove(self.index)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddDrawingStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_drawing_style"
|
||||||
|
bl_label = "Add Drawing Style"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
new = bpy.context.scene.DocProperties.drawing_styles.add()
|
||||||
|
new.name = "New Drawing Style"
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveDrawingStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.remove_drawing_style"
|
||||||
|
bl_label = "Remove Drawing Style"
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
bpy.context.scene.DocProperties.drawing_styles.remove(self.index)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class SaveDrawingStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.save_drawing_style"
|
||||||
|
bl_label = "Save Drawing Style"
|
||||||
|
index: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
space = self.get_view_3d()
|
||||||
|
style = {
|
||||||
|
"bpy.data.worlds[0].color": tuple(bpy.data.worlds[0].color),
|
||||||
|
"bpy.context.scene.render.engine": bpy.context.scene.render.engine,
|
||||||
|
"bpy.context.scene.render.film_transparent": bpy.context.scene.render.film_transparent,
|
||||||
|
"bpy.context.scene.display.shading.show_object_outline": bpy.context.scene.display.shading.show_object_outline,
|
||||||
|
"bpy.context.scene.display.shading.show_cavity": bpy.context.scene.display.shading.show_cavity,
|
||||||
|
"bpy.context.scene.display.shading.cavity_type": bpy.context.scene.display.shading.cavity_type,
|
||||||
|
"bpy.context.scene.display.shading.curvature_ridge_factor": bpy.context.scene.display.shading.curvature_ridge_factor,
|
||||||
|
"bpy.context.scene.display.shading.curvature_valley_factor": bpy.context.scene.display.shading.curvature_valley_factor,
|
||||||
|
"bpy.context.scene.view_settings.view_transform": bpy.context.scene.view_settings.view_transform,
|
||||||
|
"bpy.context.scene.display.shading.light": bpy.context.scene.display.shading.light,
|
||||||
|
"bpy.context.scene.display.shading.color_type": bpy.context.scene.display.shading.color_type,
|
||||||
|
"bpy.context.scene.display.shading.single_color": tuple(bpy.context.scene.display.shading.single_color),
|
||||||
|
"bpy.context.scene.display.shading.show_shadows": bpy.context.scene.display.shading.show_shadows,
|
||||||
|
"bpy.context.scene.display.shading.shadow_intensity": bpy.context.scene.display.shading.shadow_intensity,
|
||||||
|
"bpy.context.scene.display.light_direction": tuple(bpy.context.scene.display.light_direction),
|
||||||
|
"bpy.context.scene.view_settings.use_curve_mapping": bpy.context.scene.view_settings.use_curve_mapping,
|
||||||
|
"space.overlay.show_wireframes": space.overlay.show_wireframes,
|
||||||
|
"space.overlay.wireframe_threshold": space.overlay.wireframe_threshold,
|
||||||
|
"space.overlay.show_floor": space.overlay.show_floor,
|
||||||
|
"space.overlay.show_axis_x": space.overlay.show_axis_x,
|
||||||
|
"space.overlay.show_axis_y": space.overlay.show_axis_y,
|
||||||
|
"space.overlay.show_axis_z": space.overlay.show_axis_z,
|
||||||
|
"space.overlay.show_object_origins": space.overlay.show_object_origins,
|
||||||
|
"space.overlay.show_relationship_lines": space.overlay.show_relationship_lines,
|
||||||
|
}
|
||||||
|
if self.index:
|
||||||
|
index = int(self.index)
|
||||||
|
else:
|
||||||
|
index = bpy.context.active_object.data.BIMCameraProperties.active_drawing_style_index
|
||||||
|
bpy.context.scene.DocProperties.drawing_styles[index].raster_style = json.dumps(style)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def get_view_3d(self):
|
||||||
|
for area in bpy.context.screen.areas:
|
||||||
|
if area.type != "VIEW_3D":
|
||||||
|
continue
|
||||||
|
for space in area.spaces:
|
||||||
|
if space.type != "VIEW_3D":
|
||||||
|
continue
|
||||||
|
return space
|
||||||
|
|
||||||
|
|
||||||
|
class ActivateDrawingStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.activate_drawing_style"
|
||||||
|
bl_label = "Activate Drawing Style"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
if context.scene.camera.data.BIMCameraProperties.active_drawing_style_index < len(
|
||||||
|
bpy.context.scene.DocProperties.drawing_styles
|
||||||
|
):
|
||||||
|
self.drawing_style = bpy.context.scene.DocProperties.drawing_styles[
|
||||||
|
context.scene.camera.data.BIMCameraProperties.active_drawing_style_index
|
||||||
|
]
|
||||||
|
self.set_raster_style()
|
||||||
|
self.set_query()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def set_raster_style(self):
|
||||||
|
space = self.get_view_3d()
|
||||||
|
style = json.loads(self.drawing_style.raster_style)
|
||||||
|
bpy.data.worlds[0].color = style["bpy.data.worlds[0].color"]
|
||||||
|
bpy.context.scene.render.engine = style["bpy.context.scene.render.engine"]
|
||||||
|
bpy.context.scene.render.film_transparent = style["bpy.context.scene.render.film_transparent"]
|
||||||
|
bpy.context.scene.display.shading.show_object_outline = style[
|
||||||
|
"bpy.context.scene.display.shading.show_object_outline"
|
||||||
|
]
|
||||||
|
bpy.context.scene.display.shading.show_cavity = style["bpy.context.scene.display.shading.show_cavity"]
|
||||||
|
bpy.context.scene.display.shading.cavity_type = style["bpy.context.scene.display.shading.cavity_type"]
|
||||||
|
bpy.context.scene.display.shading.curvature_ridge_factor = style[
|
||||||
|
"bpy.context.scene.display.shading.curvature_ridge_factor"
|
||||||
|
]
|
||||||
|
bpy.context.scene.display.shading.curvature_valley_factor = style[
|
||||||
|
"bpy.context.scene.display.shading.curvature_valley_factor"
|
||||||
|
]
|
||||||
|
bpy.context.scene.view_settings.view_transform = style["bpy.context.scene.view_settings.view_transform"]
|
||||||
|
bpy.context.scene.display.shading.light = style["bpy.context.scene.display.shading.light"]
|
||||||
|
bpy.context.scene.display.shading.color_type = style["bpy.context.scene.display.shading.color_type"]
|
||||||
|
bpy.context.scene.display.shading.single_color = style["bpy.context.scene.display.shading.single_color"]
|
||||||
|
bpy.context.scene.display.shading.show_shadows = style["bpy.context.scene.display.shading.show_shadows"]
|
||||||
|
bpy.context.scene.display.shading.shadow_intensity = style["bpy.context.scene.display.shading.shadow_intensity"]
|
||||||
|
bpy.context.scene.display.light_direction = style["bpy.context.scene.display.light_direction"]
|
||||||
|
|
||||||
|
bpy.context.scene.view_settings.use_curve_mapping = style["bpy.context.scene.view_settings.use_curve_mapping"]
|
||||||
|
space.overlay.show_wireframes = style["space.overlay.show_wireframes"]
|
||||||
|
space.overlay.wireframe_threshold = style["space.overlay.wireframe_threshold"]
|
||||||
|
space.overlay.show_floor = style["space.overlay.show_floor"]
|
||||||
|
space.overlay.show_axis_x = style["space.overlay.show_axis_x"]
|
||||||
|
space.overlay.show_axis_y = style["space.overlay.show_axis_y"]
|
||||||
|
space.overlay.show_axis_z = style["space.overlay.show_axis_z"]
|
||||||
|
space.overlay.show_object_origins = style["space.overlay.show_object_origins"]
|
||||||
|
space.overlay.show_relationship_lines = style["space.overlay.show_relationship_lines"]
|
||||||
|
|
||||||
|
def set_query(self):
|
||||||
|
self.selector = ifcopenshell.util.selector.Selector()
|
||||||
|
self.include_global_ids = []
|
||||||
|
self.exclude_global_ids = []
|
||||||
|
for ifc_file in bpy.context.scene.DocProperties.ifc_files:
|
||||||
|
try:
|
||||||
|
ifc = ifcopenshell.open(ifc_file.name)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
if self.drawing_style.include_query:
|
||||||
|
results = self.selector.parse(ifc, self.drawing_style.include_query)
|
||||||
|
self.include_global_ids.extend([e.GlobalId for e in results])
|
||||||
|
if self.drawing_style.exclude_query:
|
||||||
|
results = self.selector.parse(ifc, self.drawing_style.exclude_query)
|
||||||
|
self.exclude_global_ids.extend([e.GlobalId for e in results])
|
||||||
|
if self.drawing_style.include_query:
|
||||||
|
self.parse_filter_query("INCLUDE")
|
||||||
|
if self.drawing_style.exclude_query:
|
||||||
|
self.parse_filter_query("EXCLUDE")
|
||||||
|
|
||||||
|
def parse_filter_query(self, mode):
|
||||||
|
if mode == "INCLUDE":
|
||||||
|
objects = bpy.context.scene.objects
|
||||||
|
elif mode == "EXCLUDE":
|
||||||
|
objects = bpy.context.visible_objects
|
||||||
|
for obj in objects:
|
||||||
|
if mode == "INCLUDE":
|
||||||
|
obj.hide_viewport = False # Note: this breaks alt-H
|
||||||
|
global_id = obj.BIMObjectProperties.attributes.get("GlobalId")
|
||||||
|
if not global_id:
|
||||||
|
continue
|
||||||
|
global_id = global_id.string_value
|
||||||
|
if mode == "INCLUDE":
|
||||||
|
if global_id not in self.include_global_ids:
|
||||||
|
obj.hide_viewport = True # Note: this breaks alt-H
|
||||||
|
elif mode == "EXCLUDE":
|
||||||
|
if global_id in self.exclude_global_ids:
|
||||||
|
obj.hide_viewport = True # Note: this breaks alt-H
|
||||||
|
|
||||||
|
def get_view_3d(self):
|
||||||
|
for area in bpy.context.screen.areas:
|
||||||
|
if area.type != "VIEW_3D":
|
||||||
|
continue
|
||||||
|
for space in area.spaces:
|
||||||
|
if space.type != "VIEW_3D":
|
||||||
|
continue
|
||||||
|
return space
|
||||||
|
|
||||||
|
|
||||||
|
class EditVectorStyle(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.edit_vector_style"
|
||||||
|
bl_label = "Edit Vector Style"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
camera = context.scene.camera
|
||||||
|
vector_style = context.scene.DocProperties.drawing_styles[
|
||||||
|
camera.data.BIMCameraProperties.active_drawing_style_index
|
||||||
|
].vector_style
|
||||||
|
bpy.data.texts.load(os.path.join(context.scene.BIMProperties.data_dir, "styles", vector_style + ".css"))
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveSheet(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.remove_sheet"
|
||||||
|
bl_label = "Remove Sheet"
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
props.sheets.remove(self.index)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddSchedule(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_schedule"
|
||||||
|
bl_label = "Add Schedule"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
new = bpy.context.scene.DocProperties.schedules.add()
|
||||||
|
new.name = "SCHEDULE {}".format(len(bpy.context.scene.DocProperties.schedules))
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveSchedule(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.remove_schedule"
|
||||||
|
bl_label = "Remove Schedule"
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
props.schedules.remove(self.index)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class SelectScheduleFile(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.select_schedule_file"
|
||||||
|
bl_label = "Select Documentation IFC File"
|
||||||
|
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||||
|
filter_glob: bpy.props.StringProperty(default="*.ods", options={"HIDDEN"})
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
props.schedules[props.active_schedule_index].file = self.filepath
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
context.window_manager.fileselect_add(self)
|
||||||
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
|
||||||
|
class BuildSchedule(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.build_schedule"
|
||||||
|
bl_label = "Build Schedule"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
schedule = props.schedules[props.active_schedule_index]
|
||||||
|
schedule_creator = scheduler.Scheduler()
|
||||||
|
outfile = os.path.join(bpy.context.scene.BIMProperties.data_dir, "schedules", schedule.name + ".svg")
|
||||||
|
schedule_creator.schedule(schedule.file, outfile)
|
||||||
|
open_with_user_command(bpy.context.preferences.addons["blenderbim"].preferences.svg_command, outfile)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddScheduleToSheet(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_schedule_to_sheet"
|
||||||
|
bl_label = "Add Schedule To Sheet"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
sheet_builder = sheeter.SheetBuilder()
|
||||||
|
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
|
||||||
|
sheet_builder.add_schedule(
|
||||||
|
props.schedules[props.active_schedule_index].name, props.sheets[props.active_sheet_index].name
|
||||||
|
)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddDrawingStyleAttribute(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_drawing_style_attribute"
|
||||||
|
bl_label = "Add Drawing Style Attribute"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.camera.data.BIMCameraProperties
|
||||||
|
context.scene.DocProperties.drawing_styles[props.active_drawing_style_index].attributes.add()
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveDrawingStyleAttribute(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.remove_drawing_style_attribute"
|
||||||
|
bl_label = "Remove Drawing Style Attribute"
|
||||||
|
index: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
props = bpy.context.scene.camera.data.BIMCameraProperties
|
||||||
|
context.scene.DocProperties.drawing_styles[props.active_drawing_style_index].attributes.remove(self.index)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class RefreshDrawingList(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.refresh_drawing_list"
|
||||||
|
bl_label = "Refresh Drawing List"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
while len(bpy.context.scene.DocProperties.drawings) > 0:
|
||||||
|
bpy.context.scene.DocProperties.drawings.remove(0)
|
||||||
|
for obj in bpy.context.scene.objects:
|
||||||
|
if not isinstance(obj.data, bpy.types.Camera):
|
||||||
|
continue
|
||||||
|
if "IfcAnnotation/" in obj.name and obj.users_collection[0].name == obj.name:
|
||||||
|
new = bpy.context.scene.DocProperties.drawings.add()
|
||||||
|
new.name = obj.name.split("/")[1]
|
||||||
|
new.camera = obj
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CleanWireframes(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.clean_wireframes"
|
||||||
|
bl_label = "Clean Wireframes"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
objects = bpy.data.objects
|
||||||
|
if bpy.context.selected_objects:
|
||||||
|
objects = bpy.context.selected_objects
|
||||||
|
for obj in objects:
|
||||||
|
if not isinstance(obj.data, bpy.types.Mesh):
|
||||||
|
continue
|
||||||
|
# TODO: probably breaks i18n
|
||||||
|
if not obj.modifiers.get("EdgeSplit"):
|
||||||
|
obj.modifiers.new("EdgeSplit", "EDGE_SPLIT")
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CopyGrid(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_grid"
|
||||||
|
bl_label = "Add Grid"
|
||||||
|
bl_options = {"UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
proj_coll = helper.get_project_collection(context.scene)
|
||||||
|
view_coll, camera = helper.get_active_drawing(context.scene)
|
||||||
|
if view_coll is None:
|
||||||
|
return {"CANCELLED"}
|
||||||
|
is_ortho = camera.data.type == "ORTHO"
|
||||||
|
bounds = helper.ortho_view_frame(camera.data) if is_ortho else None
|
||||||
|
clipping = is_ortho and camera.data.BIMCameraProperties.target_view in ("PLAN_VIEW", "REFLECTED_PLAN_VIEW")
|
||||||
|
elevating = is_ortho and camera.data.BIMCameraProperties.target_view in ("ELEVATION_VIEW", "SECTION_VIEW")
|
||||||
|
|
||||||
|
def grep(coll):
|
||||||
|
return [obj for obj in coll.all_objects if obj.name.startswith("IfcGridAxis")]
|
||||||
|
|
||||||
|
def clone(src):
|
||||||
|
dst = src.copy()
|
||||||
|
dst.data = dst.data.copy()
|
||||||
|
return dst
|
||||||
|
|
||||||
|
def disassemble(obj):
|
||||||
|
mesh = bmesh.new()
|
||||||
|
mesh.verts.ensure_lookup_table()
|
||||||
|
mesh.from_mesh(obj.data)
|
||||||
|
return obj, mesh
|
||||||
|
|
||||||
|
def assemble(obj, mesh):
|
||||||
|
mesh.to_mesh(obj.data)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def localize(obj, mesh):
|
||||||
|
# convert to camera coords
|
||||||
|
mesh.transform(camera.matrix_world.inverted() @ obj.matrix_world)
|
||||||
|
obj.matrix_world = camera.matrix_world
|
||||||
|
return obj, mesh
|
||||||
|
|
||||||
|
def clip(mesh):
|
||||||
|
# clip segment against camera view bounds
|
||||||
|
mesh.verts.ensure_lookup_table()
|
||||||
|
points = [v.co for v in mesh.verts[0:2]]
|
||||||
|
points = helper.clip_segment(bounds, points)
|
||||||
|
if points is None:
|
||||||
|
return None
|
||||||
|
mesh.verts[0].co = points[0]
|
||||||
|
mesh.verts[1].co = points[1]
|
||||||
|
return mesh
|
||||||
|
|
||||||
|
def elev(mesh):
|
||||||
|
# put camera-perpendicular segments vertically
|
||||||
|
mesh.verts.ensure_lookup_table()
|
||||||
|
points = [v.co for v in mesh.verts[0:2]]
|
||||||
|
points = helper.elevate_segment(bounds, points)
|
||||||
|
if points is None:
|
||||||
|
return None
|
||||||
|
points = helper.clip_segment(bounds, points)
|
||||||
|
if points is None:
|
||||||
|
return None
|
||||||
|
mesh.verts[0].co = points[0]
|
||||||
|
mesh.verts[1].co = points[1]
|
||||||
|
return mesh
|
||||||
|
|
||||||
|
for obj in grep(view_coll):
|
||||||
|
view_coll.objects.unlink(obj)
|
||||||
|
|
||||||
|
grid = [localize(*disassemble(clone(obj))) for obj in grep(proj_coll)]
|
||||||
|
|
||||||
|
if clipping:
|
||||||
|
grid = [(obj, clip(mesh)) for obj, mesh in grid]
|
||||||
|
elif elevating:
|
||||||
|
grid = [(obj, elev(mesh)) for obj, mesh in grid]
|
||||||
|
|
||||||
|
for obj, mesh in grid:
|
||||||
|
if mesh is not None:
|
||||||
|
view_coll.objects.link(assemble(obj, mesh))
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddSectionsAnnotations(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_sections_annotations"
|
||||||
|
bl_label = "Add Sections"
|
||||||
|
bl_options = {"UNDO"}
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
scene = context.scene
|
||||||
|
view_coll, camera = helper.get_active_drawing(scene)
|
||||||
|
is_ortho = camera.data.type == "ORTHO"
|
||||||
|
if not is_ortho:
|
||||||
|
return {"CANCELLED"}
|
||||||
|
bounds = helper.ortho_view_frame(camera.data) if is_ortho else None
|
||||||
|
|
||||||
|
drawings = [
|
||||||
|
d
|
||||||
|
for d in scene.DocProperties.drawings
|
||||||
|
if (
|
||||||
|
d.camera is not camera
|
||||||
|
and d.camera.data.type == "ORTHO"
|
||||||
|
and d.camera.data.BIMCameraProperties.target_view == "SECTION_VIEW"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
def sideview(cam):
|
||||||
|
# leftmost and righmost points of camera view area, local coords
|
||||||
|
xmin, xmax, _, _, _, _ = helper.ortho_view_frame(cam.data, margin=0)
|
||||||
|
proj = camera.matrix_world.inverted() @ cam.matrix_world
|
||||||
|
p_l = proj @ Vector((xmin, 0, 0))
|
||||||
|
p_r = proj @ Vector((xmax, 0, 0))
|
||||||
|
return helper.clip_segment(bounds, (p_l, p_r))
|
||||||
|
|
||||||
|
def annotation(drawing, points):
|
||||||
|
# object with path geometry
|
||||||
|
name = drawing.name
|
||||||
|
curve = bpy.data.curves.new(f"Section/{name}", "CURVE")
|
||||||
|
spline = curve.splines.new("POLY") # has 1 initial point
|
||||||
|
spline.points.add(1)
|
||||||
|
p1, p2 = points
|
||||||
|
z = bounds[4] - 1e-5 # zmin
|
||||||
|
spline.points[0].co = (p1.x, p1.y, z, 1)
|
||||||
|
spline.points[1].co = (p2.x, p2.y, z, 1)
|
||||||
|
obj = bpy.data.objects.new(f"IfcAnnotation/Section/{name}", curve)
|
||||||
|
obj.matrix_world = camera.matrix_world
|
||||||
|
return obj
|
||||||
|
|
||||||
|
for d in drawings:
|
||||||
|
points = sideview(d.camera)
|
||||||
|
if points is None:
|
||||||
|
continue
|
||||||
|
obj = annotation(d, points)
|
||||||
|
view_coll.objects.link(obj)
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|||||||
+29
-18
@@ -1,10 +1,10 @@
|
|||||||
from mathutils import Matrix
|
|
||||||
import bgl
|
import bgl
|
||||||
|
from mathutils import Matrix
|
||||||
from gpu.types import GPUShader
|
from gpu.types import GPUShader
|
||||||
from gpu_extras.batch import batch_for_shader
|
from gpu_extras.batch import batch_for_shader
|
||||||
|
|
||||||
|
|
||||||
class BaseShader():
|
class BaseShader:
|
||||||
"""Wrapepr for GPUShader
|
"""Wrapepr for GPUShader
|
||||||
To use for viewport decorations with geometry generated on GPU side.
|
To use for viewport decorations with geometry generated on GPU side.
|
||||||
|
|
||||||
@@ -85,14 +85,15 @@ class BaseShader():
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# NB: libcode arg doesn't work
|
# NB: libcode arg doesn't work
|
||||||
self.prog = GPUShader(vertexcode=self.VERT_GLSL,
|
self.prog = GPUShader(
|
||||||
fragcode=self.FRAG_GLSL,
|
vertexcode=self.VERT_GLSL,
|
||||||
geocode=self.LIB_GLSL + self.GEOM_GLSL,
|
fragcode=self.FRAG_GLSL,
|
||||||
defines=self.DEF_GLSL)
|
geocode=self.LIB_GLSL + self.GEOM_GLSL,
|
||||||
|
defines=self.DEF_GLSL,
|
||||||
|
)
|
||||||
|
|
||||||
def batch(self, indices=None, **data):
|
def batch(self, indices=None, **data):
|
||||||
"""Returns automatic GPUBatch filled with provided parameters
|
"""Returns automatic GPUBatch filled with provided parameters"""
|
||||||
"""
|
|
||||||
batch = batch_for_shader(self.prog, self.TYPE, data, indices=indices)
|
batch = batch_for_shader(self.prog, self.TYPE, data, indices=indices)
|
||||||
batch.program_set(self.prog)
|
batch.program_set(self.prog)
|
||||||
return batch
|
return batch
|
||||||
@@ -113,23 +114,26 @@ class BaseShader():
|
|||||||
region = ctx.region
|
region = ctx.region
|
||||||
region3d = ctx.region_data
|
region3d = ctx.region_data
|
||||||
try:
|
try:
|
||||||
self.prog.uniform_float('viewMatrix', region3d.perspective_matrix)
|
self.prog.uniform_float("viewMatrix", region3d.perspective_matrix)
|
||||||
except ValueError: # unused uniform
|
except ValueError: # unused uniform
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
self.prog.uniform_float('winSize', (region.width / 2, region.height / 2))
|
self.prog.uniform_float("winSize", (region.width / 2, region.height / 2))
|
||||||
except ValueError: # unused uniform
|
except ValueError: # unused uniform
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BaseLinesShader(BaseShader):
|
class BaseLinesShader(BaseShader):
|
||||||
"""Draws line segments with gaps around vertices at endpoints
|
"""Draws line segments with gaps around vertices at endpoints"""
|
||||||
"""
|
|
||||||
TYPE = 'LINES'
|
|
||||||
|
|
||||||
DEF_GLSL = BaseShader.DEF_GLSL + """
|
TYPE = "LINES"
|
||||||
|
|
||||||
|
DEF_GLSL = (
|
||||||
|
BaseShader.DEF_GLSL
|
||||||
|
+ """
|
||||||
#define GAP_SIZE {gap_size}
|
#define GAP_SIZE {gap_size}
|
||||||
"""
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
GEOM_GLSL = """
|
GEOM_GLSL = """
|
||||||
layout(lines) in;
|
layout(lines) in;
|
||||||
@@ -171,6 +175,7 @@ class GizmoShader(BaseShader):
|
|||||||
|
|
||||||
Scaling to match viewport is partially controlled by user preferences and gizmo code.
|
Scaling to match viewport is partially controlled by user preferences and gizmo code.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# TODO: add some magic to respect gizmo settings/params
|
# TODO: add some magic to respect gizmo settings/params
|
||||||
|
|
||||||
VERT_GLSL = """
|
VERT_GLSL = """
|
||||||
@@ -187,12 +192,15 @@ class GizmoShader(BaseShader):
|
|||||||
class DotsGizmoShader(GizmoShader):
|
class DotsGizmoShader(GizmoShader):
|
||||||
"""Draws circles of radius 1 around points"""
|
"""Draws circles of radius 1 around points"""
|
||||||
|
|
||||||
TYPE = 'POINTS'
|
TYPE = "POINTS"
|
||||||
|
|
||||||
DEF_GLSL = BaseShader.DEF_GLSL + """
|
DEF_GLSL = (
|
||||||
|
BaseShader.DEF_GLSL
|
||||||
|
+ """
|
||||||
#define CIRCLE_SEGMENTS 12
|
#define CIRCLE_SEGMENTS 12
|
||||||
#define CIRCLE_RADIUS 8
|
#define CIRCLE_RADIUS 8
|
||||||
"""
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
GEOM_GLSL = """
|
GEOM_GLSL = """
|
||||||
layout(points) in;
|
layout(points) in;
|
||||||
@@ -235,11 +243,14 @@ class DotsGizmoShader(GizmoShader):
|
|||||||
class ExtrusionGuidesShader(GizmoShader):
|
class ExtrusionGuidesShader(GizmoShader):
|
||||||
"""Draws lines and add cross in XY plane at endpoints"""
|
"""Draws lines and add cross in XY plane at endpoints"""
|
||||||
|
|
||||||
TYPE = 'LINES'
|
TYPE = "LINES"
|
||||||
|
|
||||||
DEF_GLSL = BaseShader.DEF_GLSL + """
|
DEF_GLSL = (
|
||||||
|
BaseShader.DEF_GLSL
|
||||||
|
+ """
|
||||||
#define CROSS_SIZE .5
|
#define CROSS_SIZE .5
|
||||||
"""
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
GEOM_GLSL = """
|
GEOM_GLSL = """
|
||||||
uniform mat4 ModelViewProjectionMatrix;
|
uniform mat4 ModelViewProjectionMatrix;
|
||||||
@@ -110,3 +110,213 @@ class BIM_PT_camera(Panel):
|
|||||||
row.operator("bim.create_drawing", text="Create Drawing 2.0")
|
row.operator("bim.create_drawing", text="Create Drawing 2.0")
|
||||||
op = row.operator("bim.open_view", icon="URL", text="")
|
op = row.operator("bim.open_view", icon="URL", text="")
|
||||||
op.view = context.active_object.name.split("/")[1]
|
op.view = context.active_object.name.split("/")[1]
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_drawings(Panel):
|
||||||
|
bl_label = "SVG Drawings"
|
||||||
|
bl_idname = "BIM_PT_drawings"
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "output"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.add_drawing")
|
||||||
|
row.operator("bim.refresh_drawing_list", icon="FILE_REFRESH", text="")
|
||||||
|
|
||||||
|
if props.drawings:
|
||||||
|
if props.active_drawing_index < len(props.drawings):
|
||||||
|
op = row.operator("bim.open_view", icon="URL", text="")
|
||||||
|
op.view = props.drawings[props.active_drawing_index].name
|
||||||
|
row.operator("bim.remove_drawing", icon="X", text="").index = props.active_drawing_index
|
||||||
|
layout.template_list("BIM_UL_generic", "", props, "drawings", props, "active_drawing_index")
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.operator("bim.add_ifc_file")
|
||||||
|
|
||||||
|
for index, ifc_file in enumerate(props.ifc_files):
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(ifc_file, "name", text="IFC #{}".format(index + 1))
|
||||||
|
row.operator("bim.select_doc_ifc_file", icon="FILE_FOLDER", text="").index = index
|
||||||
|
row.operator("bim.remove_ifc_file", icon="X", text="").index = index
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_schedules(Panel):
|
||||||
|
bl_label = "ODS Schedules"
|
||||||
|
bl_idname = "BIM_PT_schedules"
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "output"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.add_schedule")
|
||||||
|
|
||||||
|
if props.schedules:
|
||||||
|
row.operator("bim.build_schedule", icon="LINENUMBERS_ON", text="")
|
||||||
|
row.operator("bim.remove_schedule", icon="X", text="").index = props.active_schedule_index
|
||||||
|
|
||||||
|
layout.template_list("BIM_UL_generic", "", props, "schedules", props, "active_schedule_index")
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props.schedules[props.active_schedule_index], "file")
|
||||||
|
row.operator("bim.select_schedule_file", icon="FILE_FOLDER", text="")
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_sheets(Panel):
|
||||||
|
bl_label = "SVG Sheets"
|
||||||
|
bl_idname = "BIM_PT_sheets"
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "output"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(props, "titleblock", text="")
|
||||||
|
row.operator("bim.add_sheet")
|
||||||
|
|
||||||
|
if props.sheets:
|
||||||
|
row.operator("bim.open_sheet", icon="URL", text="")
|
||||||
|
row.operator("bim.remove_sheet", icon="X", text="").index = props.active_sheet_index
|
||||||
|
|
||||||
|
layout.template_list("BIM_UL_generic", "", props, "sheets", props, "active_sheet_index")
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.add_drawing_to_sheet")
|
||||||
|
row.operator("bim.add_schedule_to_sheet")
|
||||||
|
row = layout.row()
|
||||||
|
row.operator("bim.create_sheets")
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_text(Panel):
|
||||||
|
bl_label = "Text Paper Space"
|
||||||
|
bl_idname = "BIM_PT_text"
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "data"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return type(context.curve) is bpy.types.TextCurve
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
props = context.active_object.data.BIMTextProperties
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.operator("bim.propagate_text_data")
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, "font_size")
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, "symbol")
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, "related_element")
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.operator("bim.add_variable")
|
||||||
|
|
||||||
|
for index, variable in enumerate(props.variables):
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(variable, "name")
|
||||||
|
row.operator("bim.remove_variable", icon="X", text="").index = index
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(variable, "prop_key")
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_annotation_utilities(Panel):
|
||||||
|
bl_idname = "BIM_PT_annotation_utilities"
|
||||||
|
bl_label = "Annotation"
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
bl_category = "BlenderBIM"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.clean_wireframes")
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.link_ifc")
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.add_grid")
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.add_sections_annotations")
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
op = row.operator("bim.add_annotation", text="Dim", icon="ARROW_LEFTRIGHT")
|
||||||
|
op.obj_name = "Dimension"
|
||||||
|
op.data_type = "curve"
|
||||||
|
op = row.operator("bim.add_annotation", text="Dim (Eq)", icon="ARROW_LEFTRIGHT")
|
||||||
|
op.obj_name = "Equal"
|
||||||
|
op.data_type = "curve"
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
op = row.operator("bim.add_annotation", text="Text", icon="SMALL_CAPS")
|
||||||
|
op.data_type = "text"
|
||||||
|
op = row.operator("bim.add_annotation", text="Leader", icon="TRACKING_BACKWARDS")
|
||||||
|
op.obj_name = "Leader"
|
||||||
|
op.data_type = "curve"
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
op = row.operator("bim.add_annotation", text="Stair Arrow", icon="SCREEN_BACK")
|
||||||
|
op.obj_name = "Stair"
|
||||||
|
op.data_type = "curve"
|
||||||
|
op = row.operator("bim.add_annotation", text="Hidden", icon="CON_TRACKTO")
|
||||||
|
op.obj_name = "Hidden"
|
||||||
|
op.data_type = "mesh"
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
op = row.operator("bim.add_annotation", text="Level (Plan)", icon="SORTBYEXT")
|
||||||
|
op.obj_name = "Plan Level"
|
||||||
|
op.data_type = "curve"
|
||||||
|
op = row.operator("bim.add_annotation", text="Level (Section)", icon="TRIA_DOWN")
|
||||||
|
op.obj_name = "Section Level"
|
||||||
|
op.data_type = "curve"
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
op = row.operator("bim.add_annotation", text="Breakline", icon="FCURVE")
|
||||||
|
op.obj_name = "Break"
|
||||||
|
op.data_type = "mesh"
|
||||||
|
op = row.operator("bim.add_annotation", text="Misc", icon="MESH_MONKEY")
|
||||||
|
op.obj_name = "Misc"
|
||||||
|
op.data_type = "mesh"
|
||||||
|
|
||||||
|
props = bpy.context.scene.DocProperties
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("bim.add_drawing")
|
||||||
|
row.operator("bim.refresh_drawing_list", icon="FILE_REFRESH", text="")
|
||||||
|
|
||||||
|
if props.drawings:
|
||||||
|
if props.active_drawing_index < len(props.drawings):
|
||||||
|
op = row.operator("bim.open_view", icon="URL", text="")
|
||||||
|
op.view = props.drawings[props.active_drawing_index].name
|
||||||
|
row.operator("bim.remove_drawing", icon="X", text="").index = props.active_drawing_index
|
||||||
|
layout.template_list("BIM_UL_drawinglist", "", props, "drawings", props, "active_drawing_index")
|
||||||
|
|
||||||
|
layout.prop(props, "should_draw_decorations")
|
||||||
|
layout.prop(props, "decorations_colour")
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_UL_drawinglist(bpy.types.UIList):
|
||||||
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
|
if item:
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(item, "name", text="", emboss=False)
|
||||||
|
op = row.operator("bim.open_view_camera", icon="OUTLINER_OB_CAMERA", text="")
|
||||||
|
op.view_name = item.name
|
||||||
|
else:
|
||||||
|
layout.label(text="", translate=False)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,93 +5,6 @@ from bpy.types import Panel
|
|||||||
from bpy.props import StringProperty, BoolProperty
|
from bpy.props import StringProperty, BoolProperty
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_drawings(Panel):
|
|
||||||
bl_label = "SVG Drawings"
|
|
||||||
bl_idname = "BIM_PT_drawings"
|
|
||||||
bl_space_type = "PROPERTIES"
|
|
||||||
bl_region_type = "WINDOW"
|
|
||||||
bl_context = "output"
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
props = bpy.context.scene.DocProperties
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.add_drawing")
|
|
||||||
row.operator("bim.refresh_drawing_list", icon="FILE_REFRESH", text="")
|
|
||||||
|
|
||||||
if props.drawings:
|
|
||||||
if props.active_drawing_index < len(props.drawings):
|
|
||||||
op = row.operator("bim.open_view", icon="URL", text="")
|
|
||||||
op.view = props.drawings[props.active_drawing_index].name
|
|
||||||
row.operator("bim.remove_drawing", icon="X", text="").index = props.active_drawing_index
|
|
||||||
layout.template_list("BIM_UL_generic", "", props, "drawings", props, "active_drawing_index")
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.operator("bim.add_ifc_file")
|
|
||||||
|
|
||||||
for index, ifc_file in enumerate(props.ifc_files):
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.prop(ifc_file, "name", text="IFC #{}".format(index + 1))
|
|
||||||
row.operator("bim.select_doc_ifc_file", icon="FILE_FOLDER", text="").index = index
|
|
||||||
row.operator("bim.remove_ifc_file", icon="X", text="").index = index
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_schedules(Panel):
|
|
||||||
bl_label = "ODS Schedules"
|
|
||||||
bl_idname = "BIM_PT_schedules"
|
|
||||||
bl_space_type = "PROPERTIES"
|
|
||||||
bl_region_type = "WINDOW"
|
|
||||||
bl_context = "output"
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
props = bpy.context.scene.DocProperties
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.add_schedule")
|
|
||||||
|
|
||||||
if props.schedules:
|
|
||||||
row.operator("bim.build_schedule", icon="LINENUMBERS_ON", text="")
|
|
||||||
row.operator("bim.remove_schedule", icon="X", text="").index = props.active_schedule_index
|
|
||||||
|
|
||||||
layout.template_list("BIM_UL_generic", "", props, "schedules", props, "active_schedule_index")
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props.schedules[props.active_schedule_index], "file")
|
|
||||||
row.operator("bim.select_schedule_file", icon="FILE_FOLDER", text="")
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_sheets(Panel):
|
|
||||||
bl_label = "SVG Sheets"
|
|
||||||
bl_idname = "BIM_PT_sheets"
|
|
||||||
bl_space_type = "PROPERTIES"
|
|
||||||
bl_region_type = "WINDOW"
|
|
||||||
bl_context = "output"
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
props = bpy.context.scene.DocProperties
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.prop(props, "titleblock", text="")
|
|
||||||
row.operator("bim.add_sheet")
|
|
||||||
|
|
||||||
if props.sheets:
|
|
||||||
row.operator("bim.open_sheet", icon="URL", text="")
|
|
||||||
row.operator("bim.remove_sheet", icon="X", text="").index = props.active_sheet_index
|
|
||||||
|
|
||||||
layout.template_list("BIM_UL_generic", "", props, "sheets", props, "active_sheet_index")
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.add_drawing_to_sheet")
|
|
||||||
row.operator("bim.add_schedule_to_sheet")
|
|
||||||
row = layout.row()
|
|
||||||
row.operator("bim.create_sheets")
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_section_plane(Panel):
|
class BIM_PT_section_plane(Panel):
|
||||||
bl_label = "Temporary Section Cutaways"
|
bl_label = "Temporary Section Cutaways"
|
||||||
bl_idname = "BIM_PT_section_plane"
|
bl_idname = "BIM_PT_section_plane"
|
||||||
@@ -115,43 +28,6 @@ class BIM_PT_section_plane(Panel):
|
|||||||
row.operator("bim.remove_section_plane")
|
row.operator("bim.remove_section_plane")
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_text(Panel):
|
|
||||||
bl_label = "Text Paper Space"
|
|
||||||
bl_idname = "BIM_PT_text"
|
|
||||||
bl_space_type = "PROPERTIES"
|
|
||||||
bl_region_type = "WINDOW"
|
|
||||||
bl_context = "data"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def poll(cls, context):
|
|
||||||
return type(context.curve) is bpy.types.TextCurve
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
props = context.active_object.data.BIMTextProperties
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.operator("bim.propagate_text_data")
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, "font_size")
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, "symbol")
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(props, "related_element")
|
|
||||||
|
|
||||||
row = layout.row()
|
|
||||||
row.operator("bim.add_variable")
|
|
||||||
|
|
||||||
for index, variable in enumerate(props.variables):
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.prop(variable, "name")
|
|
||||||
row.operator("bim.remove_variable", icon="X", text="").index = index
|
|
||||||
row = layout.row()
|
|
||||||
row.prop(variable, "prop_key")
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_UL_generic(bpy.types.UIList):
|
class BIM_UL_generic(bpy.types.UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
if item:
|
if item:
|
||||||
@@ -160,17 +36,6 @@ class BIM_UL_generic(bpy.types.UIList):
|
|||||||
layout.label(text="", translate=False)
|
layout.label(text="", translate=False)
|
||||||
|
|
||||||
|
|
||||||
class BIM_UL_drawinglist(bpy.types.UIList):
|
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
|
||||||
if item:
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.prop(item, "name", text="", emboss=False)
|
|
||||||
op = row.operator("bim.open_view_camera", icon="OUTLINER_OB_CAMERA", text="")
|
|
||||||
op.view_name = item.name
|
|
||||||
else:
|
|
||||||
layout.label(text="", translate=False)
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_UL_topics(bpy.types.UIList):
|
class BIM_UL_topics(bpy.types.UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
ob = data
|
ob = data
|
||||||
@@ -224,81 +89,6 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
|||||||
row.prop(self, "should_hide_empty_props")
|
row.prop(self, "should_hide_empty_props")
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_annotation_utilities(Panel):
|
|
||||||
bl_idname = "BIM_PT_annotation_utilities"
|
|
||||||
bl_label = "Annotation"
|
|
||||||
bl_space_type = "VIEW_3D"
|
|
||||||
bl_region_type = "UI"
|
|
||||||
bl_category = "BlenderBIM"
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
layout = self.layout
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.clean_wireframes")
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.link_ifc")
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.add_grid")
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.add_sections_annotations")
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
op = row.operator("bim.add_annotation", text="Dim", icon="ARROW_LEFTRIGHT")
|
|
||||||
op.obj_name = "Dimension"
|
|
||||||
op.data_type = "curve"
|
|
||||||
op = row.operator("bim.add_annotation", text="Dim (Eq)", icon="ARROW_LEFTRIGHT")
|
|
||||||
op.obj_name = "Equal"
|
|
||||||
op.data_type = "curve"
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
op = row.operator("bim.add_annotation", text="Text", icon="SMALL_CAPS")
|
|
||||||
op.data_type = "text"
|
|
||||||
op = row.operator("bim.add_annotation", text="Leader", icon="TRACKING_BACKWARDS")
|
|
||||||
op.obj_name = "Leader"
|
|
||||||
op.data_type = "curve"
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
op = row.operator("bim.add_annotation", text="Stair Arrow", icon="SCREEN_BACK")
|
|
||||||
op.obj_name = "Stair"
|
|
||||||
op.data_type = "curve"
|
|
||||||
op = row.operator("bim.add_annotation", text="Hidden", icon="CON_TRACKTO")
|
|
||||||
op.obj_name = "Hidden"
|
|
||||||
op.data_type = "mesh"
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
op = row.operator("bim.add_annotation", text="Level (Plan)", icon="SORTBYEXT")
|
|
||||||
op.obj_name = "Plan Level"
|
|
||||||
op.data_type = "curve"
|
|
||||||
op = row.operator("bim.add_annotation", text="Level (Section)", icon="TRIA_DOWN")
|
|
||||||
op.obj_name = "Section Level"
|
|
||||||
op.data_type = "curve"
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
op = row.operator("bim.add_annotation", text="Breakline", icon="FCURVE")
|
|
||||||
op.obj_name = "Break"
|
|
||||||
op.data_type = "mesh"
|
|
||||||
op = row.operator("bim.add_annotation", text="Misc", icon="MESH_MONKEY")
|
|
||||||
op.obj_name = "Misc"
|
|
||||||
op.data_type = "mesh"
|
|
||||||
|
|
||||||
props = bpy.context.scene.DocProperties
|
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.operator("bim.add_drawing")
|
|
||||||
row.operator("bim.refresh_drawing_list", icon="FILE_REFRESH", text="")
|
|
||||||
|
|
||||||
if props.drawings:
|
|
||||||
if props.active_drawing_index < len(props.drawings):
|
|
||||||
op = row.operator("bim.open_view", icon="URL", text="")
|
|
||||||
op.view = props.drawings[props.active_drawing_index].name
|
|
||||||
row.operator("bim.remove_drawing", icon="X", text="").index = props.active_drawing_index
|
|
||||||
layout.template_list("BIM_UL_drawinglist", "", props, "drawings", props, "active_drawing_index")
|
|
||||||
|
|
||||||
layout.prop(props, "should_draw_decorations")
|
|
||||||
layout.prop(props, "decorations_colour")
|
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_misc_utilities(Panel):
|
class BIM_PT_misc_utilities(Panel):
|
||||||
bl_idname = "BIM_PT_misc_utilities"
|
bl_idname = "BIM_PT_misc_utilities"
|
||||||
bl_label = "Miscellaneous"
|
bl_label = "Miscellaneous"
|
||||||
|
|||||||
Reference in New Issue
Block a user