mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 01:11:40 +00:00
You can now specify a target view when creating a new drawing. See #1153.
This commit is contained in:
@@ -65,66 +65,14 @@ class Operator:
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddDrawing(bpy.types.Operator):
|
||||
class AddDrawing(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.add_drawing"
|
||||
bl_label = "Add Drawing"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return IfcStore.get_file()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
drawing_name = tool.Drawing.ensure_unique_drawing_name("UNTITLED")
|
||||
if not bpy.data.collections.get("Views"):
|
||||
context.scene.collection.children.link(bpy.data.collections.new("Views"))
|
||||
views_collection = bpy.data.collections.get("Views")
|
||||
view_collection = bpy.data.collections.new("IfcGroup/" + drawing_name)
|
||||
views_collection.children.link(view_collection)
|
||||
camera = bpy.data.objects.new(drawing_name, bpy.data.cameras.new(drawing_name))
|
||||
camera.location = (0, 0, 1.5) # The view shall be 1.5m above the origin
|
||||
camera.data.type = "ORTHO"
|
||||
camera.data.ortho_scale = 50 # The default of 6m is too small
|
||||
camera.data.clip_end = 10 # A slightly more reasonable default
|
||||
if context.scene.unit_settings.system == "IMPERIAL":
|
||||
camera.data.BIMCameraProperties.diagram_scale = '1/8"=1\'-0"|1/96'
|
||||
else:
|
||||
camera.data.BIMCameraProperties.diagram_scale = "1:100|1/100"
|
||||
context.scene.camera = camera
|
||||
view_collection.objects.link(camera)
|
||||
area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
|
||||
area.spaces[0].region_3d.view_perspective = "CAMERA"
|
||||
bpy.ops.bim.assign_class(obj=camera.name, ifc_class="IfcAnnotation", predefined_type="DRAWING")
|
||||
bpy.ops.bim.activate_drawing_style()
|
||||
|
||||
bpy.ops.bim.add_group()
|
||||
group = self.file.by_id(sorted(GroupData.groups.keys())[-1])
|
||||
ifcopenshell.api.run("group.edit_group", self.file, **{"group": group, "attributes": {"Name": drawing_name}})
|
||||
bpy.ops.bim.assign_group(product=camera.name, group=group.id())
|
||||
pset = ifcopenshell.api.run(
|
||||
"pset.add_pset",
|
||||
self.file,
|
||||
**{
|
||||
"product": self.file.by_id(camera.BIMObjectProperties.ifc_definition_id),
|
||||
"name": "EPset_Drawing",
|
||||
},
|
||||
)
|
||||
ifcopenshell.api.run(
|
||||
"pset.edit_pset",
|
||||
self.file,
|
||||
**{
|
||||
"pset": pset,
|
||||
"properties": {"TargetView": "PLAN_VIEW", "Scale": "1/100"},
|
||||
"pset_template": blenderbim.bim.schema.ifc.psetqto.get_by_name("EPset_Drawing"),
|
||||
},
|
||||
)
|
||||
PsetData.load(IfcStore.get_file(), camera.BIMObjectProperties.ifc_definition_id)
|
||||
tool.Drawing.import_drawings()
|
||||
return {"FINISHED"}
|
||||
self.props = context.scene.DocProperties
|
||||
core.add_drawing(tool.Ifc, tool.Collector, tool.Drawing, target_view=self.props.target_view, location_hint=None)
|
||||
|
||||
|
||||
class CreateDrawing(bpy.types.Operator):
|
||||
@@ -143,6 +91,7 @@ class CreateDrawing(bpy.types.Operator):
|
||||
camera = context.scene.camera
|
||||
return (
|
||||
IfcStore.get_file()
|
||||
and camera
|
||||
and camera.type == "CAMERA"
|
||||
and camera.data.type == "ORTHO"
|
||||
and camera.BIMObjectProperties.ifc_definition_id
|
||||
|
||||
@@ -180,8 +180,11 @@ class BIM_PT_drawings(Panel):
|
||||
op.view = self.props.active_drawing.name
|
||||
op = row.operator("bim.activate_view", icon="OUTLINER_OB_CAMERA", text="")
|
||||
op.drawing = self.props.active_drawing.ifc_definition_id
|
||||
row.operator("bim.create_drawing", text="", icon="OUTPUT")
|
||||
row.operator("bim.remove_drawing", icon="X", text="").index = self.props.active_drawing_index
|
||||
self.layout.template_list("BIM_UL_drawinglist", "", self.props, "drawings", self.props, "active_drawing_index")
|
||||
self.layout.template_list(
|
||||
"BIM_UL_drawinglist", "", self.props, "drawings", self.props, "active_drawing_index"
|
||||
)
|
||||
|
||||
# Commented out until federated drawing generation is rebuilt
|
||||
# row = self.layout.row()
|
||||
|
||||
@@ -96,3 +96,18 @@ def load_drawings(drawing):
|
||||
|
||||
def disable_editing_drawings(drawing):
|
||||
drawing.disable_editing_drawings()
|
||||
|
||||
|
||||
def add_drawing(ifc, collector, drawing, target_view=None, location_hint=None):
|
||||
drawing_name = drawing.ensure_unique_drawing_name("UNTITLED")
|
||||
drawing_matrix = drawing.generate_drawing_matrix(target_view, location_hint)
|
||||
camera = drawing.create_camera(drawing_name, drawing_matrix)
|
||||
# Not yet refactored
|
||||
element = drawing.run_assign_class_operator(obj=camera, ifc_class="IfcAnnotation", predefined_type="DRAWING")
|
||||
group = ifc.run("group.add_group")
|
||||
ifc.run("group.edit_group", group=group, attributes={"Name": drawing_name})
|
||||
ifc.run("group.assign_group", group=group, product=element)
|
||||
collector.assign(camera)
|
||||
pset = ifc.run("pset.add_pset", product=element, name="EPset_Drawing")
|
||||
ifc.run("pset.edit_pset", pset=pset, properties={"TargetView": target_view, "Scale": "1/100"})
|
||||
drawing.import_drawings()
|
||||
|
||||
@@ -135,6 +135,7 @@ class Debug:
|
||||
|
||||
@interface
|
||||
class Drawing:
|
||||
def create_camera(cls, name, matrix): pass
|
||||
def create_svg_sheet(cls, document, titleblock): pass
|
||||
def disable_editing_drawings(cls): pass
|
||||
def disable_editing_sheets(cls): pass
|
||||
@@ -144,8 +145,10 @@ class Drawing:
|
||||
def enable_editing_sheets(cls): pass
|
||||
def enable_editing_text(cls, obj): pass
|
||||
def enable_editing_text_product(cls, obj): pass
|
||||
def ensure_unique_drawing_name(cls, name): pass
|
||||
def ensure_unique_identification(cls, identification): pass
|
||||
def export_text_literal_attributes(cls, obj): pass
|
||||
def generate_drawing_matrix(cls, target_view, location_hint): pass
|
||||
def generate_sheet_identification(cls): pass
|
||||
def get_sheet_filename(cls, document): pass
|
||||
def get_text_literal(cls, obj): pass
|
||||
@@ -155,6 +158,7 @@ class Drawing:
|
||||
def import_text_attributes(cls, obj): pass
|
||||
def import_text_product(cls, obj): pass
|
||||
def open_svg(cls, filepath): pass
|
||||
def run_assign_class_operator(cls, obj=None, ifc_class=None, predefined_type=None): pass
|
||||
def update_text_value(cls, obj): pass
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import os
|
||||
import re
|
||||
import bpy
|
||||
import mathutils
|
||||
import webbrowser
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
@@ -27,6 +28,21 @@ import blenderbim.bim.module.drawing.sheeter as sheeter
|
||||
|
||||
|
||||
class Drawing(blenderbim.core.tool.Drawing):
|
||||
@classmethod
|
||||
def create_camera(cls, name, matrix):
|
||||
camera = bpy.data.objects.new(name, bpy.data.cameras.new(name))
|
||||
camera.location = (0, 0, 1.5) # The view shall be 1.5m above the origin
|
||||
camera.data.type = "ORTHO"
|
||||
camera.data.ortho_scale = 50 # The default of 6m is too small
|
||||
camera.data.clip_end = 10 # A slightly more reasonable default
|
||||
if bpy.context.scene.unit_settings.system == "IMPERIAL":
|
||||
camera.data.BIMCameraProperties.diagram_scale = '1/8"=1\'-0"|1/96'
|
||||
else:
|
||||
camera.data.BIMCameraProperties.diagram_scale = "1:100|1/100"
|
||||
camera.matrix_world = matrix
|
||||
bpy.context.scene.collection.objects.link(camera)
|
||||
return camera
|
||||
|
||||
@classmethod
|
||||
def create_svg_sheet(cls, document, titleblock):
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
@@ -97,6 +113,10 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
name += " - " + document.Name or "Unnamed"
|
||||
return name
|
||||
|
||||
@classmethod
|
||||
def generate_drawing_matrix(cls, target_view, location_hint):
|
||||
return mathutils.Matrix()
|
||||
|
||||
@classmethod
|
||||
def generate_sheet_identification(cls):
|
||||
number = len([d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "DOCUMENTATION"])
|
||||
@@ -174,6 +194,11 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", filename + ".svg"),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def run_assign_class_operator(cls, obj=None, ifc_class=None, predefined_type=None):
|
||||
bpy.ops.bim.assign_class(obj=obj.name, ifc_class=ifc_class, predefined_type=predefined_type)
|
||||
return tool.Ifc.get_entity(obj)
|
||||
|
||||
@classmethod
|
||||
def update_text_value(cls, obj):
|
||||
element = cls.get_text_literal(obj)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import blenderbim.core.drawing as subject
|
||||
from test.core.bootstrap import ifc, drawing
|
||||
from test.core.bootstrap import ifc, drawing, collector
|
||||
|
||||
|
||||
class TestEnableEditingText:
|
||||
@@ -137,3 +137,23 @@ class TestDisableEditingDrawings:
|
||||
def test_run(self, drawing):
|
||||
drawing.disable_editing_drawings().should_be_called()
|
||||
subject.disable_editing_drawings(drawing)
|
||||
|
||||
|
||||
class TestAddDrawing:
|
||||
def test_run(self, ifc, collector, drawing):
|
||||
drawing.ensure_unique_drawing_name("UNTITLED").should_be_called().will_return("name")
|
||||
drawing.generate_drawing_matrix("target_view", "location_hint").should_be_called().will_return("matrix")
|
||||
drawing.create_camera("name", "matrix").should_be_called().will_return("obj")
|
||||
drawing.run_assign_class_operator(
|
||||
obj="obj", ifc_class="IfcAnnotation", predefined_type="DRAWING"
|
||||
).should_be_called().will_return("element")
|
||||
ifc.run("group.add_group").should_be_called().will_return("group")
|
||||
ifc.run("group.edit_group", group="group", attributes={"Name": "name"}).should_be_called()
|
||||
ifc.run("group.assign_group", group="group", product="element").should_be_called()
|
||||
collector.assign("obj").should_be_called()
|
||||
ifc.run("pset.add_pset", product="element", name="EPset_Drawing").should_be_called().will_return("pset")
|
||||
ifc.run(
|
||||
"pset.edit_pset", pset="pset", properties={"TargetView": "target_view", "Scale": "1/100"}
|
||||
).should_be_called()
|
||||
drawing.import_drawings().should_be_called()
|
||||
subject.add_drawing(ifc, collector, drawing, target_view="target_view", location_hint="location_hint")
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import mathutils
|
||||
import ifcopenshell
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
@@ -30,6 +31,17 @@ class TestImplementsTool(NewFile):
|
||||
assert isinstance(subject(), blenderbim.core.tool.Drawing)
|
||||
|
||||
|
||||
class TestCreateCamera(NewFile):
|
||||
def test_run(self):
|
||||
obj = subject.create_camera("Name", mathutils.Matrix())
|
||||
assert obj.name == "Name"
|
||||
assert obj.matrix_world == mathutils.Matrix()
|
||||
assert obj.data.type == "ORTHO"
|
||||
assert obj.data.ortho_scale == 50
|
||||
assert obj.data.clip_end == 10
|
||||
assert obj.users_collection[0] == bpy.context.scene.collection
|
||||
|
||||
|
||||
class TestCreateSvgSheet(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
@@ -149,6 +161,11 @@ class TestGetSheetFilename(NewFile):
|
||||
subject.get_sheet_filename(document) == "X - FOOBAR"
|
||||
|
||||
|
||||
class TestGenerateDrawingMatrix(NewFile):
|
||||
def test_returning_the_origin_as_a_fallback(self):
|
||||
assert subject.generate_drawing_matrix("PLAN_VIEW", None) == mathutils.Matrix()
|
||||
|
||||
|
||||
class TestGenerateSheetIdentification(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
@@ -266,6 +283,11 @@ class TestOpenSvg(NewFile):
|
||||
pass
|
||||
|
||||
|
||||
class TestRunAssignClassOperator(NewFile):
|
||||
def test_nothing(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestUpdateTextValue(NewFile):
|
||||
def test_updating_arbitrary_strings(self):
|
||||
TestGetTextLiteral().test_run()
|
||||
|
||||
Reference in New Issue
Block a user