mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 22:16:41 +00:00
Refactor - moved some helpers functions to tool
This commit is contained in:
@@ -267,35 +267,6 @@ def convert_property_group_from_si(property_group, skip_props=()):
|
|||||||
setattr(property_group, prop_name, prop_value)
|
setattr(property_group, prop_name, prop_value)
|
||||||
|
|
||||||
|
|
||||||
def draw_image_for_ifc_profile(draw, profile, size):
|
|
||||||
"""generates image based on `profile` using `PIL.ImageDraw`"""
|
|
||||||
settings = ifcopenshell.geom.settings()
|
|
||||||
settings.set(settings.INCLUDE_CURVES, True)
|
|
||||||
shape = ifcopenshell.geom.create_shape(settings, profile)
|
|
||||||
verts = shape.verts
|
|
||||||
edges = shape.edges
|
|
||||||
|
|
||||||
grouped_verts = [[verts[i], verts[i + 1]] for i in range(0, len(verts), 3)]
|
|
||||||
grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
|
|
||||||
|
|
||||||
max_x = max([v[0] for v in grouped_verts])
|
|
||||||
min_x = min([v[0] for v in grouped_verts])
|
|
||||||
max_y = max([v[1] for v in grouped_verts])
|
|
||||||
min_y = min([v[1] for v in grouped_verts])
|
|
||||||
|
|
||||||
dim_x = max_x - min_x
|
|
||||||
dim_y = max_y - min_y
|
|
||||||
max_dim = max([dim_x, dim_y])
|
|
||||||
scale = 100 / max_dim
|
|
||||||
|
|
||||||
for vert in grouped_verts:
|
|
||||||
vert[0] = round(scale * (vert[0] - min_x)) + ((size / 2) - scale * (dim_x / 2))
|
|
||||||
vert[1] = round(scale * (vert[1] - min_y)) + ((size / 2) - scale * (dim_y / 2))
|
|
||||||
|
|
||||||
for e in grouped_edges:
|
|
||||||
draw.line((tuple(grouped_verts[e[0]]), tuple(grouped_verts[e[1]])), fill="white", width=2)
|
|
||||||
|
|
||||||
|
|
||||||
class IfcHeaderExtractor:
|
class IfcHeaderExtractor:
|
||||||
def __init__(self, filepath: str):
|
def __init__(self, filepath: str):
|
||||||
self.filepath = filepath
|
self.filepath = filepath
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import blenderbim.core.geometry as core
|
|||||||
from blenderbim.bim.helper import convert_property_group_from_si
|
from blenderbim.bim.helper import convert_property_group_from_si
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.module.model.window import create_bm_window, create_bm_box, update_simple_openings
|
from blenderbim.bim.module.model.window import create_bm_window, create_bm_box, update_simple_openings
|
||||||
from blenderbim.bim.module.model.helper import replace_ifc_representation_for_object
|
|
||||||
|
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
@@ -80,20 +79,20 @@ def update_door_modifier_representation(context):
|
|||||||
elevation_representation = ifcopenshell.api.run(
|
elevation_representation = ifcopenshell.api.run(
|
||||||
"geometry.add_door_representation", ifc_file, **representation_data
|
"geometry.add_door_representation", ifc_file, **representation_data
|
||||||
)
|
)
|
||||||
replace_ifc_representation_for_object(ifc_file, profile, obj, elevation_representation)
|
tool.Model.replace_object_ifc_representation(profile, obj, elevation_representation)
|
||||||
|
|
||||||
# MODEL_VIEW representation
|
# MODEL_VIEW representation
|
||||||
body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
|
body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
|
||||||
representation_data["context"] = body
|
representation_data["context"] = body
|
||||||
model_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data)
|
model_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data)
|
||||||
replace_ifc_representation_for_object(ifc_file, body, obj, model_representation)
|
tool.Model.replace_object_ifc_representation(body, obj, model_representation)
|
||||||
|
|
||||||
# PLAN_VIEW representation
|
# PLAN_VIEW representation
|
||||||
plan = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW")
|
plan = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW")
|
||||||
if plan:
|
if plan:
|
||||||
representation_data["context"] = plan
|
representation_data["context"] = plan
|
||||||
plan_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data)
|
plan_representation = ifcopenshell.api.run("geometry.add_door_representation", ifc_file, **representation_data)
|
||||||
replace_ifc_representation_for_object(ifc_file, plan, obj, plan_representation)
|
tool.Model.replace_object_ifc_representation(plan, obj, plan_representation)
|
||||||
|
|
||||||
# adding switch representation at the end instead of changing order of representations
|
# adding switch representation at the end instead of changing order of representations
|
||||||
# to prevent #2744
|
# to prevent #2744
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
|
||||||
# Copyright (C) 2023 @Andrej730
|
|
||||||
#
|
|
||||||
# This file is part of BlenderBIM Add-on.
|
|
||||||
#
|
|
||||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import bpy
|
|
||||||
import bmesh
|
|
||||||
import ifcopenshell
|
|
||||||
import ifcopenshell.util.unit
|
|
||||||
import blenderbim.core.geometry as core
|
|
||||||
import blenderbim.tool as tool
|
|
||||||
|
|
||||||
|
|
||||||
def get_ifc_context_or_create(ifc_file, context_type, context_identifier, target_view):
|
|
||||||
ifc_context = ifcopenshell.util.representation.get_context(ifc_file, context_type, context_identifier, target_view)
|
|
||||||
if not ifc_context:
|
|
||||||
parent_context = ifcopenshell.util.representation.get_context(ifc_file, context_type)
|
|
||||||
ifc_context = ifcopenshell.api.run(
|
|
||||||
"context.add_context",
|
|
||||||
ifc_file,
|
|
||||||
context_type=context_type,
|
|
||||||
context_identifier=context_identifier,
|
|
||||||
target_view=target_view,
|
|
||||||
parent=parent_context,
|
|
||||||
)
|
|
||||||
return ifc_context
|
|
||||||
|
|
||||||
|
|
||||||
def replace_ifc_representation_for_object(ifc_file, ifc_context, obj, new_representation):
|
|
||||||
ifc_element = tool.Ifc.get_entity(obj)
|
|
||||||
old_representation = ifcopenshell.util.representation.get_representation(
|
|
||||||
ifc_element, ifc_context.ContextType, ifc_context.ContextIdentifier, ifc_context.TargetView
|
|
||||||
)
|
|
||||||
|
|
||||||
if old_representation:
|
|
||||||
old_representation = tool.Geometry.resolve_mapped_representation(old_representation)
|
|
||||||
for inverse in ifc_file.get_inverse(old_representation):
|
|
||||||
ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation)
|
|
||||||
ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=old_representation)
|
|
||||||
else:
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation
|
|
||||||
)
|
|
||||||
core.switch_representation(
|
|
||||||
tool.Ifc,
|
|
||||||
tool.Geometry,
|
|
||||||
obj=obj,
|
|
||||||
representation=new_representation,
|
|
||||||
should_reload=True,
|
|
||||||
is_global=True,
|
|
||||||
should_sync_changes_first=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -32,7 +32,6 @@ from . import wall, slab, profile, mep
|
|||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.module.model.data import AuthoringData
|
from blenderbim.bim.module.model.data import AuthoringData
|
||||||
from blenderbim.bim.module.model.prop import store_cursor_position
|
from blenderbim.bim.module.model.prop import store_cursor_position
|
||||||
from blenderbim.bim.helper import draw_image_for_ifc_profile
|
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from bpy_extras.object_utils import AddObjectHelper
|
from bpy_extras.object_utils import AddObjectHelper
|
||||||
from . import prop
|
from . import prop
|
||||||
@@ -374,7 +373,7 @@ class LoadTypeThumbnails(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
material = ifcopenshell.util.element.get_material(element)
|
material = ifcopenshell.util.element.get_material(element)
|
||||||
if material and material.is_a("IfcMaterialProfileSet"):
|
if material and material.is_a("IfcMaterialProfileSet"):
|
||||||
profile = material.MaterialProfiles[0].Profile
|
profile = material.MaterialProfiles[0].Profile
|
||||||
draw_image_for_ifc_profile(draw, profile, size)
|
tool.Profile.draw_image_for_ifc_profile(draw, profile, size)
|
||||||
|
|
||||||
elif material and material.is_a("IfcMaterialLayerSet"):
|
elif material and material.is_a("IfcMaterialLayerSet"):
|
||||||
thicknesses = [l.LayerThickness for l in material.MaterialLayers]
|
thicknesses = [l.LayerThickness for l in material.MaterialLayers]
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ from bpy.props import FloatProperty, IntProperty, BoolProperty
|
|||||||
from bmesh.types import BMVert
|
from bmesh.types import BMVert
|
||||||
from blenderbim.bim.helper import convert_property_group_from_si
|
from blenderbim.bim.helper import convert_property_group_from_si
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.module.model.helper import replace_ifc_representation_for_object
|
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
|
|
||||||
|
|
||||||
@@ -148,13 +147,13 @@ def update_window_modifier_representation(context):
|
|||||||
elevation_representation = ifcopenshell.api.run(
|
elevation_representation = ifcopenshell.api.run(
|
||||||
"geometry.add_window_representation", ifc_file, **representation_data
|
"geometry.add_window_representation", ifc_file, **representation_data
|
||||||
)
|
)
|
||||||
replace_ifc_representation_for_object(ifc_file, profile, obj, elevation_representation)
|
tool.Model.replace_object_ifc_representation(profile, obj, elevation_representation)
|
||||||
|
|
||||||
# MODEL_VIEW representation
|
# MODEL_VIEW representation
|
||||||
body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
|
body = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
|
||||||
representation_data["context"] = body
|
representation_data["context"] = body
|
||||||
model_representation = ifcopenshell.api.run("geometry.add_window_representation", ifc_file, **representation_data)
|
model_representation = ifcopenshell.api.run("geometry.add_window_representation", ifc_file, **representation_data)
|
||||||
replace_ifc_representation_for_object(ifc_file, body, obj, model_representation)
|
tool.Model.replace_object_ifc_representation(body, obj, model_representation)
|
||||||
|
|
||||||
# PLAN_VIEW representation
|
# PLAN_VIEW representation
|
||||||
plan = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW")
|
plan = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "Body", "PLAN_VIEW")
|
||||||
@@ -163,7 +162,7 @@ def update_window_modifier_representation(context):
|
|||||||
plan_representation = ifcopenshell.api.run(
|
plan_representation = ifcopenshell.api.run(
|
||||||
"geometry.add_window_representation", ifc_file, **representation_data
|
"geometry.add_window_representation", ifc_file, **representation_data
|
||||||
)
|
)
|
||||||
replace_ifc_representation_for_object(ifc_file, plan, obj, plan_representation)
|
tool.Model.replace_object_ifc_representation(plan, obj, plan_representation)
|
||||||
|
|
||||||
# adding switch representation at the end instead of changing order of representations
|
# adding switch representation at the end instead of changing order of representations
|
||||||
# to prevent #2744
|
# to prevent #2744
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import blenderbim.tool as tool
|
|||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.prop import StrProperty, Attribute
|
from blenderbim.bim.prop import StrProperty, Attribute
|
||||||
from blenderbim.bim.module.profile.data import ProfileData
|
from blenderbim.bim.module.profile.data import ProfileData
|
||||||
from blenderbim.bim.helper import draw_image_for_ifc_profile
|
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
from bpy.props import (
|
from bpy.props import (
|
||||||
PointerProperty,
|
PointerProperty,
|
||||||
@@ -79,7 +78,7 @@ def generate_thumbnail_for_active_profile():
|
|||||||
size = 128
|
size = 128
|
||||||
img = Image.new("RGBA", (size, size))
|
img = Image.new("RGBA", (size, size))
|
||||||
draw = ImageDraw.Draw(img)
|
draw = ImageDraw.Draw(img)
|
||||||
draw_image_for_ifc_profile(draw, profile, size)
|
tool.Profile.draw_image_for_ifc_profile(draw, profile, size)
|
||||||
pixels = [item for sublist in img.getdata() for item in sublist]
|
pixels = [item for sublist in img.getdata() for item in sublist]
|
||||||
|
|
||||||
# save generated image to preview collection
|
# save generated image to preview collection
|
||||||
|
|||||||
@@ -398,7 +398,23 @@ class Misc:
|
|||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Model:
|
class Model:
|
||||||
pass
|
def convert_si_to_unit(cls, value): pass
|
||||||
|
def convert_unit_to_si(cls, value): pass
|
||||||
|
def export_curve(cls, position, edge_indices, points=None): pass
|
||||||
|
def export_points(cls, position, indices): pass
|
||||||
|
def export_profile(cls, obj, position=None): pass
|
||||||
|
def generate_occurrence_name(cls, element_type, ifc_class): pass
|
||||||
|
def get_extrusion(cls, representation): pass
|
||||||
|
def import_profile(cls, profile, obj=None, position=None): pass
|
||||||
|
def import_curve(cls, obj, position, curve): pass
|
||||||
|
def import_rectangle(cls, obj, position, profile): pass
|
||||||
|
def load_openings(cls, element, openings): pass
|
||||||
|
def clear_scene_openings(cls): pass
|
||||||
|
def get_material_layer_parameters(cls, element): pass
|
||||||
|
def get_manual_booleans(cls, element): pass
|
||||||
|
def get_wall_axis(cls, obj, layers=None): pass
|
||||||
|
def regenerate_array(cls, parent, data): pass
|
||||||
|
def replace_object_ifc_representation(cls, ifc_file, ifc_context, obj, new_representation): pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
@@ -461,6 +477,11 @@ class Project:
|
|||||||
def set_default_modeling_dimensions(cls): pass
|
def set_default_modeling_dimensions(cls): pass
|
||||||
|
|
||||||
|
|
||||||
|
@interface
|
||||||
|
class Profile:
|
||||||
|
def draw_image_for_ifc_profile(cls, draw, profile, size): pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Pset:
|
class Pset:
|
||||||
def get_element_pset(cls, element, pset_name): pass
|
def get_element_pset(cls, element, pset_name): pass
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ from blenderbim.tool.model import Model
|
|||||||
from blenderbim.tool.owner import Owner
|
from blenderbim.tool.owner import Owner
|
||||||
from blenderbim.tool.patch import Patch
|
from blenderbim.tool.patch import Patch
|
||||||
from blenderbim.tool.project import Project
|
from blenderbim.tool.project import Project
|
||||||
|
from blenderbim.tool.profile import Profile
|
||||||
from blenderbim.tool.pset import Pset
|
from blenderbim.tool.pset import Pset
|
||||||
from blenderbim.tool.qto import Qto
|
from blenderbim.tool.qto import Qto
|
||||||
from blenderbim.tool.resource import Resource
|
from blenderbim.tool.resource import Resource
|
||||||
@@ -51,4 +52,4 @@ from blenderbim.tool.system import System
|
|||||||
from blenderbim.tool.type import Type
|
from blenderbim.tool.type import Type
|
||||||
from blenderbim.tool.unit import Unit
|
from blenderbim.tool.unit import Unit
|
||||||
from blenderbim.tool.search import Search
|
from blenderbim.tool.search import Search
|
||||||
from blenderbim.tool.cost import Cost
|
from blenderbim.tool.cost import Cost
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import ifcopenshell.util.placement
|
|||||||
import ifcopenshell.util.representation
|
import ifcopenshell.util.representation
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
|
import blenderbim.core.geometry as geometry
|
||||||
from mathutils import Matrix, Vector
|
from mathutils import Matrix, Vector
|
||||||
from blenderbim.bim import import_ifc
|
from blenderbim.bim import import_ifc
|
||||||
from blenderbim.bim.module.geometry.helper import Helper
|
from blenderbim.bim.module.geometry.helper import Helper
|
||||||
@@ -408,3 +409,30 @@ class Model(blenderbim.core.tool.Model):
|
|||||||
# TODO: Not sufficient, refactor OverrideDeleteTrait
|
# TODO: Not sufficient, refactor OverrideDeleteTrait
|
||||||
|
|
||||||
bpy.context.view_layer.update()
|
bpy.context.view_layer.update()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def replace_object_ifc_representation(cls, ifc_context, obj, new_representation):
|
||||||
|
ifc_file = tool.Ifc.get()
|
||||||
|
ifc_element = tool.Ifc.get_entity(obj)
|
||||||
|
old_representation = ifcopenshell.util.representation.get_representation(
|
||||||
|
ifc_element, ifc_context.ContextType, ifc_context.ContextIdentifier, ifc_context.TargetView
|
||||||
|
)
|
||||||
|
|
||||||
|
if old_representation:
|
||||||
|
old_representation = tool.Geometry.resolve_mapped_representation(old_representation)
|
||||||
|
for inverse in ifc_file.get_inverse(old_representation):
|
||||||
|
ifcopenshell.util.element.replace_attribute(inverse, old_representation, new_representation)
|
||||||
|
ifcopenshell.api.run("geometry.remove_representation", ifc_file, representation=old_representation)
|
||||||
|
else:
|
||||||
|
ifcopenshell.api.run(
|
||||||
|
"geometry.assign_representation", ifc_file, product=ifc_element, representation=new_representation
|
||||||
|
)
|
||||||
|
geometry.switch_representation(
|
||||||
|
tool.Ifc,
|
||||||
|
tool.Geometry,
|
||||||
|
obj=obj,
|
||||||
|
representation=new_representation,
|
||||||
|
should_reload=True,
|
||||||
|
is_global=True,
|
||||||
|
should_sync_changes_first=False,
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2022 @Andrej730
|
||||||
|
#
|
||||||
|
# This file is part of BlenderBIM Add-on.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import ifcopenshell
|
||||||
|
import ifcopenshell.util.unit
|
||||||
|
import ifcopenshell.util.placement
|
||||||
|
import ifcopenshell.util.representation
|
||||||
|
import blenderbim.core.tool
|
||||||
|
|
||||||
|
|
||||||
|
class Profile(blenderbim.core.tool.Profile):
|
||||||
|
@classmethod
|
||||||
|
def draw_image_for_ifc_profile(cls, draw, profile, size):
|
||||||
|
"""generates image based on `profile` using `PIL.ImageDraw`"""
|
||||||
|
settings = ifcopenshell.geom.settings()
|
||||||
|
settings.set(settings.INCLUDE_CURVES, True)
|
||||||
|
shape = ifcopenshell.geom.create_shape(settings, profile)
|
||||||
|
verts = shape.verts
|
||||||
|
edges = shape.edges
|
||||||
|
|
||||||
|
grouped_verts = [[verts[i], verts[i + 1]] for i in range(0, len(verts), 3)]
|
||||||
|
grouped_edges = [[edges[i], edges[i + 1]] for i in range(0, len(edges), 2)]
|
||||||
|
|
||||||
|
max_x = max([v[0] for v in grouped_verts])
|
||||||
|
min_x = min([v[0] for v in grouped_verts])
|
||||||
|
max_y = max([v[1] for v in grouped_verts])
|
||||||
|
min_y = min([v[1] for v in grouped_verts])
|
||||||
|
|
||||||
|
dim_x = max_x - min_x
|
||||||
|
dim_y = max_y - min_y
|
||||||
|
max_dim = max([dim_x, dim_y])
|
||||||
|
scale = 100 / max_dim
|
||||||
|
|
||||||
|
for vert in grouped_verts:
|
||||||
|
vert[0] = round(scale * (vert[0] - min_x)) + ((size / 2) - scale * (dim_x / 2))
|
||||||
|
vert[1] = round(scale * (vert[1] - min_y)) + ((size / 2) - scale * (dim_y / 2))
|
||||||
|
|
||||||
|
for e in grouped_edges:
|
||||||
|
draw.line((tuple(grouped_verts[e[0]]), tuple(grouped_verts[e[1]])), fill="white", width=2)
|
||||||
Reference in New Issue
Block a user