mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +00:00
New "cut decorator" that draws cut lines in drawings.
This commit is contained in:
@@ -30,6 +30,7 @@ def refresh():
|
|||||||
SchedulesData.is_loaded = False
|
SchedulesData.is_loaded = False
|
||||||
DrawingsData.is_loaded = False
|
DrawingsData.is_loaded = False
|
||||||
DecoratorData.data = {}
|
DecoratorData.data = {}
|
||||||
|
DecoratorData.cut_cache = {}
|
||||||
|
|
||||||
|
|
||||||
class ProductAssignmentsData:
|
class ProductAssignmentsData:
|
||||||
@@ -152,6 +153,7 @@ FONT_SIZES = {
|
|||||||
class DecoratorData:
|
class DecoratorData:
|
||||||
# stores 1 type of data per object
|
# stores 1 type of data per object
|
||||||
data = {}
|
data = {}
|
||||||
|
cut_cache = {}
|
||||||
|
|
||||||
# used by Ifc Annotations with ObjectType = "BATTING"
|
# used by Ifc Annotations with ObjectType = "BATTING"
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from bpy.types import SpaceView3D
|
|||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
from bpy_extras.view3d_utils import location_3d_to_region_2d
|
||||||
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
|
from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertFormat
|
||||||
|
from gpu_extras.batch import batch_for_shader
|
||||||
from blenderbim.bim.module.drawing.data import DecoratorData
|
from blenderbim.bim.module.drawing.data import DecoratorData
|
||||||
from blenderbim.bim.module.drawing.shaders import BASE_LIB_GLSL, BASE_DEF_GLSL
|
from blenderbim.bim.module.drawing.shaders import BASE_LIB_GLSL, BASE_DEF_GLSL
|
||||||
|
|
||||||
@@ -242,7 +243,7 @@ class BaseDecorator:
|
|||||||
vertices = [obj.matrix_world @ v.co for v in bm.verts]
|
vertices = [obj.matrix_world @ v.co for v in bm.verts]
|
||||||
return vertices, indices
|
return vertices, indices
|
||||||
|
|
||||||
def decorate(self, context, object):
|
def decorate(self, context, obj):
|
||||||
"""perform actual drawing stuff"""
|
"""perform actual drawing stuff"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
@@ -450,7 +451,7 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
layout(lines) in;
|
layout(lines) in;
|
||||||
layout(triangle_strip, max_vertices=MAX_POINTS) out;
|
layout(triangle_strip, max_vertices=MAX_POINTS) out;
|
||||||
|
|
||||||
void oblique_dimension_head(in vec4 dir, in float size,
|
void oblique_dimension_head(in vec4 dir, in float size,
|
||||||
in float angle, out vec4 head[OBLIQUE_HEAD_VERTS]) {
|
in float angle, out vec4 head[OBLIQUE_HEAD_VERTS]) {
|
||||||
float c = cos(angle), s = sin(angle);
|
float c = cos(angle), s = sin(angle);
|
||||||
vec4 ortho = vec4(-dir.y, dir.x, 0, 0);
|
vec4 ortho = vec4(-dir.y, dir.x, 0, 0);
|
||||||
@@ -495,22 +496,22 @@ class DimensionDecorator(BaseDecorator):
|
|||||||
|
|
||||||
// stem
|
// stem
|
||||||
do_edge_verts(p0, p1);
|
do_edge_verts(p0, p1);
|
||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
vec4 head[3];
|
vec4 head[3];
|
||||||
arrow_head(dir, viewportDrawingScale * ARROW_SIZE, ARROW_ANGLE, head);
|
arrow_head(dir, viewportDrawingScale * ARROW_SIZE, ARROW_ANGLE, head);
|
||||||
|
|
||||||
// start edge arrow
|
// start edge arrow
|
||||||
do_edge_verts( p0, WIN2CLIP( (p0w + head[1]) ) );
|
do_edge_verts( p0, WIN2CLIP( (p0w + head[1]) ) );
|
||||||
do_edge_verts_win( p0w + head[1], p0w + head[2] );
|
do_edge_verts_win( p0w + head[1], p0w + head[2] );
|
||||||
do_edge_verts( WIN2CLIP( p0w + head[2] ), p0 );
|
do_edge_verts( WIN2CLIP( p0w + head[2] ), p0 );
|
||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
|
|
||||||
// end edge arrow
|
// end edge arrow
|
||||||
do_edge_verts( p1, WIN2CLIP( p1w - head[1] ) );
|
do_edge_verts( p1, WIN2CLIP( p1w - head[1] ) );
|
||||||
do_edge_verts_win( p1w - head[1], p1w - head[2] );
|
do_edge_verts_win( p1w - head[1], p1w - head[2] );
|
||||||
do_edge_verts( WIN2CLIP( p1w - head[2] ), p1 );
|
do_edge_verts( WIN2CLIP( p1w - head[2] ), p1 );
|
||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
|
|
||||||
// stem, with gaps for arrows
|
// stem, with gaps for arrows
|
||||||
@@ -569,7 +570,7 @@ class AngleDecorator(BaseDecorator):
|
|||||||
layout(triangle_strip, max_vertices=MAX_POINTS) out;
|
layout(triangle_strip, max_vertices=MAX_POINTS) out;
|
||||||
in uint type[];
|
in uint type[];
|
||||||
in vec4 v_next_vert[];
|
in vec4 v_next_vert[];
|
||||||
|
|
||||||
// per edge shader
|
// per edge shader
|
||||||
void main() {
|
void main() {
|
||||||
// default setup for macro to work
|
// default setup for macro to work
|
||||||
@@ -981,7 +982,7 @@ class StairDecorator(BaseDecorator):
|
|||||||
if (t0 == 1u) {
|
if (t0 == 1u) {
|
||||||
vec4 head[CIRCLE_SEGS];
|
vec4 head[CIRCLE_SEGS];
|
||||||
circle_head(viewportDrawingScale * CIRCLE_SIZE, head);
|
circle_head(viewportDrawingScale * CIRCLE_SIZE, head);
|
||||||
|
|
||||||
for(int i=0; i<CIRCLE_SEGS-1; i++) {
|
for(int i=0; i<CIRCLE_SEGS-1; i++) {
|
||||||
do_edge_verts_win(p0w + head[i], p0w + head[i+1]);
|
do_edge_verts_win(p0w + head[i], p0w + head[i+1]);
|
||||||
}
|
}
|
||||||
@@ -1048,7 +1049,7 @@ class HiddenDecorator(BaseDecorator):
|
|||||||
|
|
||||||
dist = 0;
|
dist = 0;
|
||||||
do_vertex_win( p0w + gap, dir.xy);
|
do_vertex_win( p0w + gap, dir.xy);
|
||||||
|
|
||||||
dist = length(edge);
|
dist = length(edge);
|
||||||
do_vertex_win( p1w - gap, dir.xy);
|
do_vertex_win( p1w - gap, dir.xy);
|
||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
@@ -1093,7 +1094,7 @@ class MiscDecorator(BaseDecorator):
|
|||||||
layout(triangle_strip, max_vertices=MAX_POINTS) out;
|
layout(triangle_strip, max_vertices=MAX_POINTS) out;
|
||||||
|
|
||||||
out float dist; // distance from starging point along segment
|
out float dist; // distance from starging point along segment
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
DEFAULT_SETUP();
|
DEFAULT_SETUP();
|
||||||
|
|
||||||
@@ -1106,10 +1107,10 @@ class MiscDecorator(BaseDecorator):
|
|||||||
vec4 p;
|
vec4 p;
|
||||||
|
|
||||||
// NB: something should be used to affect position, otherwise compiler eliminates winsize
|
// NB: something should be used to affect position, otherwise compiler eliminates winsize
|
||||||
|
|
||||||
dist = 0;
|
dist = 0;
|
||||||
do_vertex_win( p0w + gap, dir.xy);
|
do_vertex_win( p0w + gap, dir.xy);
|
||||||
|
|
||||||
dist = length(edge);
|
dist = length(edge);
|
||||||
do_vertex_win( p1w - gap, dir.xy);
|
do_vertex_win( p1w - gap, dir.xy);
|
||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
@@ -1298,7 +1299,7 @@ class SectionLevelDecorator(LevelDecorator):
|
|||||||
// stem
|
// stem
|
||||||
dist = 0;
|
dist = 0;
|
||||||
do_vertex_win( p0w + gap, dir.xy);
|
do_vertex_win( p0w + gap, dir.xy);
|
||||||
|
|
||||||
dist = length(edge);
|
dist = length(edge);
|
||||||
do_vertex_win( p1w - gap, dir.xy);
|
do_vertex_win( p1w - gap, dir.xy);
|
||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
@@ -1436,14 +1437,14 @@ class BattingDecorator(BaseDecorator):
|
|||||||
|
|
||||||
vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1), pmw = (p0w + p1w) * .5;
|
vec4 p0w = CLIP2WIN(p0), p1w = CLIP2WIN(p1), pmw = (p0w + p1w) * .5;
|
||||||
vec4 edge = p1w - p0w, dir = normalize(edge);
|
vec4 edge = p1w - p0w, dir = normalize(edge);
|
||||||
|
|
||||||
float segment_width = batting_thickness_winspace / 2.5;
|
float segment_width = batting_thickness_winspace / 2.5;
|
||||||
vec2 batting_dimensions = vec2(segment_width, batting_thickness_winspace);
|
vec2 batting_dimensions = vec2(segment_width, batting_thickness_winspace);
|
||||||
// need to multiply by viewportDrawingScale
|
// need to multiply by viewportDrawingScale
|
||||||
// so the drawing will stay consistent on zoom in / zoom out
|
// so the drawing will stay consistent on zoom in / zoom out
|
||||||
// but since we use winspace batting dimensions we skip it
|
// but since we use winspace batting dimensions we skip it
|
||||||
mat2 m_edge_space = mat2( dir.xy, dir.yx*vec2(1,-1) );
|
mat2 m_edge_space = mat2( dir.xy, dir.yx*vec2(1,-1) );
|
||||||
|
|
||||||
// simplified rectangle + cross version to indicate batting
|
// simplified rectangle + cross version to indicate batting
|
||||||
vec4 off_y = vec4(m_edge_space * ( vec2(0, 0.5) * batting_dimensions ), 0, 0);
|
vec4 off_y = vec4(m_edge_space * ( vec2(0, 0.5) * batting_dimensions ), 0, 0);
|
||||||
do_edge_verts_win( p0w + off_y, p0w - off_y );
|
do_edge_verts_win( p0w + off_y, p0w - off_y );
|
||||||
@@ -1467,7 +1468,7 @@ class BattingDecorator(BaseDecorator):
|
|||||||
// pattern_segment_data[2] = vec2(0, 0.2);
|
// pattern_segment_data[2] = vec2(0, 0.2);
|
||||||
// pattern_segment_data[3] = vec2(0.5, 0);
|
// pattern_segment_data[3] = vec2(0.5, 0);
|
||||||
// pattern_segment_data[4] = vec2(1.0, 0.2);
|
// pattern_segment_data[4] = vec2(1.0, 0.2);
|
||||||
// pattern_segment_data[5] = vec2(0.5, 0.8);
|
// pattern_segment_data[5] = vec2(0.5, 0.8);
|
||||||
// pattern_segment_data[6] = vec2(1.0, 1.0);
|
// pattern_segment_data[6] = vec2(1.0, 1.0);
|
||||||
// zigzag pattern
|
// zigzag pattern
|
||||||
// pattern_segment_data[0] = vec2(0, 1);
|
// pattern_segment_data[0] = vec2(0, 1);
|
||||||
@@ -1830,7 +1831,7 @@ class TextDecorator(BaseDecorator):
|
|||||||
vec4 p0 = gl_in[0].gl_Position;
|
vec4 p0 = gl_in[0].gl_Position;
|
||||||
vec4 p0w = CLIP2WIN(p0);
|
vec4 p0w = CLIP2WIN(p0);
|
||||||
vec4 p;
|
vec4 p;
|
||||||
|
|
||||||
vec4 head[CIRCLE_SEGS_ASTERISK];
|
vec4 head[CIRCLE_SEGS_ASTERISK];
|
||||||
circle_head_asterisk(viewportDrawingScale * CIRCLE_SIZE, head);
|
circle_head_asterisk(viewportDrawingScale * CIRCLE_SIZE, head);
|
||||||
|
|
||||||
@@ -1887,6 +1888,147 @@ class TextDecorator(BaseDecorator):
|
|||||||
line_i += 1
|
line_i += 1
|
||||||
|
|
||||||
|
|
||||||
|
class CutDecorator:
|
||||||
|
installed = None
|
||||||
|
cache = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def install(cls, context):
|
||||||
|
if cls.installed:
|
||||||
|
cls.uninstall()
|
||||||
|
handler = cls()
|
||||||
|
cls.installed = SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_VIEW")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def uninstall(cls):
|
||||||
|
try:
|
||||||
|
SpaceView3D.draw_handler_remove(cls.installed, "WINDOW")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
cls.installed = None
|
||||||
|
|
||||||
|
def __call__(self, context):
|
||||||
|
for obj in self.get_objects(None):
|
||||||
|
self.decorate(context, obj)
|
||||||
|
|
||||||
|
def get_objects(self, collection):
|
||||||
|
return [o for o in bpy.context.visible_objects if o.type == "MESH"]
|
||||||
|
|
||||||
|
def draw_batch(self, shader_type, content_pos, color, indices=None):
|
||||||
|
shader = self.line_shader if shader_type == "LINES" else self.shader
|
||||||
|
batch = batch_for_shader(shader, shader_type, {"pos": content_pos}, indices=indices)
|
||||||
|
shader.uniform_float("color", color)
|
||||||
|
batch.draw(shader)
|
||||||
|
|
||||||
|
def decorate(self, context, obj):
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if not element:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Currently selected objects shall not be cached as they may be being moved / edited.
|
||||||
|
# If the camera is selected, we also disable the cache as the user may be moving the camera.
|
||||||
|
if obj.select_get() or context.scene.camera.select_get():
|
||||||
|
all_vertices, all_edges = None, None
|
||||||
|
else:
|
||||||
|
all_vertices, all_edges = DecoratorData.cut_cache.get(element.id(), (None, None))
|
||||||
|
|
||||||
|
if all_vertices is False:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.is_intersecting_camera(obj, context.scene.camera):
|
||||||
|
DecoratorData.cut_cache[element.id()] = (False, False)
|
||||||
|
return
|
||||||
|
|
||||||
|
if all_vertices is None:
|
||||||
|
all_vertices, all_edges = self.bisect_mesh(obj, context.scene.camera)
|
||||||
|
DecoratorData.cut_cache[element.id()] = (all_vertices, all_edges)
|
||||||
|
|
||||||
|
gpu.state.point_size_set(2)
|
||||||
|
gpu.state.blend_set("ALPHA")
|
||||||
|
|
||||||
|
### Actually drawing
|
||||||
|
# 3D_POLYLINE_UNIFORM_COLOR is good for smoothed lines since `bgl.enable(GL_LINE_SMOOTH)` is deprecated
|
||||||
|
self.line_shader = gpu.shader.from_builtin("3D_POLYLINE_UNIFORM_COLOR")
|
||||||
|
self.line_shader.bind()
|
||||||
|
# POLYLINE_UNIFORM_COLOR specific uniforms
|
||||||
|
self.line_shader.uniform_float("viewportSize", (context.region.width, context.region.height))
|
||||||
|
self.line_shader.uniform_float("lineWidth", 3.0)
|
||||||
|
|
||||||
|
# general shader
|
||||||
|
self.shader = gpu.shader.from_builtin("3D_UNIFORM_COLOR")
|
||||||
|
self.shader.bind()
|
||||||
|
|
||||||
|
green = (0.545, 0.863, 0, 1)
|
||||||
|
white = (0, 0, 0, 1)
|
||||||
|
color = green if obj.select_get() else white
|
||||||
|
self.draw_batch("LINES", all_vertices, color, all_edges)
|
||||||
|
self.draw_batch("POINTS", all_vertices, color)
|
||||||
|
|
||||||
|
def is_intersecting_camera(self, obj, camera):
|
||||||
|
# Based on separating axis theorem
|
||||||
|
plane_co = camera.matrix_world.translation
|
||||||
|
plane_no = camera.matrix_world.col[2].xyz
|
||||||
|
|
||||||
|
# Broadphase check using the bounding box
|
||||||
|
bounding_box_world_coords = [obj.matrix_world @ Vector(coord) for coord in obj.bound_box]
|
||||||
|
bounding_box_signed_distances = [plane_no.dot(v - plane_co) for v in bounding_box_world_coords]
|
||||||
|
|
||||||
|
pos_exists_bb = any(d > 0 for d in bounding_box_signed_distances)
|
||||||
|
neg_exists_bb = any(d < 0 for d in bounding_box_signed_distances)
|
||||||
|
|
||||||
|
if not (pos_exists_bb and neg_exists_bb):
|
||||||
|
return False
|
||||||
|
|
||||||
|
bm = bmesh.new()
|
||||||
|
bm.from_mesh(obj.data)
|
||||||
|
|
||||||
|
# Transform the vertices to world space
|
||||||
|
mesh_mat = obj.matrix_world
|
||||||
|
bm.transform(mesh_mat)
|
||||||
|
|
||||||
|
# Calculate the signed distances of all vertices from the plane
|
||||||
|
signed_distances = [plane_no.dot(v.co - plane_co) for v in bm.verts]
|
||||||
|
|
||||||
|
bm.free()
|
||||||
|
|
||||||
|
# Check for intersection
|
||||||
|
pos_exists = any(d > 0 for d in signed_distances)
|
||||||
|
neg_exists = any(d < 0 for d in signed_distances)
|
||||||
|
|
||||||
|
return pos_exists and neg_exists
|
||||||
|
|
||||||
|
def bisect_mesh(self, obj, camera):
|
||||||
|
camera_matrix = obj.matrix_world.inverted() @ camera.matrix_world
|
||||||
|
plane_co = camera_matrix.translation
|
||||||
|
plane_no = camera_matrix.col[2].xyz
|
||||||
|
|
||||||
|
global_offset = camera.matrix_world.col[2].xyz * -camera.data.clip_start
|
||||||
|
|
||||||
|
bm = bmesh.new()
|
||||||
|
bm.from_mesh(obj.data)
|
||||||
|
|
||||||
|
# Run the bisect operation
|
||||||
|
geom = bm.verts[:] + bm.edges[:] + bm.faces[:]
|
||||||
|
results = bmesh.ops.bisect_plane(bm, geom=geom, dist=0.0001, plane_co=plane_co, plane_no=plane_no)
|
||||||
|
|
||||||
|
vert_map = {}
|
||||||
|
verts = []
|
||||||
|
edges = []
|
||||||
|
i = 0
|
||||||
|
for geom in results["geom_cut"]:
|
||||||
|
if isinstance(geom, bmesh.types.BMVert):
|
||||||
|
verts.append(tuple((obj.matrix_world @ geom.co) + global_offset))
|
||||||
|
vert_map[geom.index] = i
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
# It seems as though edges always appear after verts
|
||||||
|
edges.append([vert_map[v.index] for v in geom.verts])
|
||||||
|
|
||||||
|
bm.free()
|
||||||
|
|
||||||
|
return verts, edges
|
||||||
|
|
||||||
|
|
||||||
class DecorationsHandler:
|
class DecorationsHandler:
|
||||||
decorators_classes = [
|
decorators_classes = [
|
||||||
DimensionDecorator,
|
DimensionDecorator,
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ from bpy.app.handlers import persistent
|
|||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def toggleDecorationsOnLoad(*args):
|
def toggleDecorationsOnLoad(*args):
|
||||||
toggle = bpy.context.scene.DocProperties.should_draw_decorations
|
if bpy.context.scene.DocProperties.should_draw_decorations:
|
||||||
if toggle:
|
|
||||||
decoration.DecorationsHandler.install(bpy.context)
|
decoration.DecorationsHandler.install(bpy.context)
|
||||||
else:
|
else:
|
||||||
decoration.DecorationsHandler.uninstall()
|
decoration.DecorationsHandler.uninstall()
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import blenderbim.bim.module.drawing.annotation as annotation
|
|||||||
import blenderbim.bim.module.drawing.sheeter as sheeter
|
import blenderbim.bim.module.drawing.sheeter as sheeter
|
||||||
import blenderbim.bim.module.drawing.scheduler as scheduler
|
import blenderbim.bim.module.drawing.scheduler as scheduler
|
||||||
import blenderbim.bim.module.drawing.helper as helper
|
import blenderbim.bim.module.drawing.helper as helper
|
||||||
|
from blenderbim.bim.module.drawing.decoration import CutDecorator
|
||||||
from blenderbim.bim.module.drawing.data import DecoratorData
|
from blenderbim.bim.module.drawing.data import DecoratorData
|
||||||
import blenderbim.bim.export_ifc
|
import blenderbim.bim.export_ifc
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
@@ -989,11 +990,13 @@ class ActivateView(bpy.types.Operator):
|
|||||||
drawing: bpy.props.IntProperty()
|
drawing: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
core.activate_drawing_view(tool.Ifc, tool.Drawing, drawing=tool.Ifc.get().by_id(self.drawing))
|
drawing = tool.Ifc.get().by_id(self.drawing)
|
||||||
|
core.activate_drawing_view(tool.Ifc, tool.Drawing, drawing=drawing)
|
||||||
bpy.context.scene.DocProperties.active_drawing_id = self.drawing
|
bpy.context.scene.DocProperties.active_drawing_id = self.drawing
|
||||||
if ifcopenshell.util.element.get_pset(drawing, "EPset_Drawing", "HasUnderlay"):
|
if ifcopenshell.util.element.get_pset(drawing, "EPset_Drawing", "HasUnderlay"):
|
||||||
bpy.ops.bim.activate_drawing_style()
|
bpy.ops.bim.activate_drawing_style()
|
||||||
core.sync_references(tool.Ifc, tool.Collector, tool.Drawing, drawing=tool.Ifc.get().by_id(self.drawing))
|
core.sync_references(tool.Ifc, tool.Collector, tool.Drawing, drawing=tool.Ifc.get().by_id(self.drawing))
|
||||||
|
CutDecorator.install(context)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
camera.location = (0, 0, 1.5) # The view shall be 1.5m above the origin
|
camera.location = (0, 0, 1.5) # The view shall be 1.5m above the origin
|
||||||
camera.data.type = "ORTHO"
|
camera.data.type = "ORTHO"
|
||||||
camera.data.ortho_scale = 50 # The default of 6m is too small
|
camera.data.ortho_scale = 50 # The default of 6m is too small
|
||||||
|
camera.data.clip_start = 0.002 # 2mm is close to zero but allows any GPU-drawn lines to be visible.
|
||||||
camera.data.clip_end = 10 # A slightly more reasonable default
|
camera.data.clip_end = 10 # A slightly more reasonable default
|
||||||
if bpy.context.scene.unit_settings.system == "IMPERIAL":
|
if bpy.context.scene.unit_settings.system == "IMPERIAL":
|
||||||
camera.data.BIMCameraProperties.diagram_scale = '1/8"=1\'-0"|1/96'
|
camera.data.BIMCameraProperties.diagram_scale = '1/8"=1\'-0"|1/96'
|
||||||
@@ -495,6 +496,7 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
camera = bpy.data.cameras.new(tool.Loader.get_mesh_name(geometry))
|
camera = bpy.data.cameras.new(tool.Loader.get_mesh_name(geometry))
|
||||||
camera.type = "ORTHO"
|
camera.type = "ORTHO"
|
||||||
camera.ortho_scale = width if width > height else height
|
camera.ortho_scale = width if width > height else height
|
||||||
|
camera.clip_start = 0.002
|
||||||
camera.clip_end = depth
|
camera.clip_end = depth
|
||||||
|
|
||||||
if width > height:
|
if width > height:
|
||||||
|
|||||||
Reference in New Issue
Block a user