From bada236b7a5e130f0031178c34165d3330094486 Mon Sep 17 00:00:00 2001 From: migius Date: Sat, 22 Dec 2018 18:55:31 +0100 Subject: DXF-importer initial port to 2.80 --- io_import_dxf/__init__.py | 93 +++++++++++++++++++++--------------------- io_import_dxf/dxfimport/do.py | 94 +++++++++++++++++++++---------------------- 2 files changed, 94 insertions(+), 93 deletions(-) (limited to 'io_import_dxf') diff --git a/io_import_dxf/__init__.py b/io_import_dxf/__init__.py index 46e84fd5..169faeb3 100644 --- a/io_import_dxf/__init__.py +++ b/io_import_dxf/__init__.py @@ -33,9 +33,9 @@ except: bl_info = { "name": "Import AutoCAD DXF Format (.dxf)", - "author": "Lukas Treyer, Manfred Moitzi (support + dxfgrabber library), Vladimir Elistratov, Bastien Montagne", - "version": (0, 8, 6), - "blender": (2, 7, 1), + "author": "Lukas Treyer, Manfred Moitzi (support + dxfgrabber library), Vladimir Elistratov, Bastien Montagne, Remigiusz Fiedler (AKA migius)", + "version": (0, 9, 6), + "blender": (2, 80, 0), "location": "File > Import > AutoCAD DXF", "description": "Import files in the Autocad DXF format (.dxf)", "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/DXF_Importer", @@ -130,7 +130,8 @@ def read(report, filename, obj_merge=BY_LAYER, import_text=True, import_light=Tr def display_groups_in_outliner(): outliners = (a for a in bpy.context.screen.areas if a.type == "OUTLINER") for outliner in outliners: - outliner.spaces[0].display_mode = "GROUPS" + pass + #outliner.spaces[0].display_mode = "GROUPS" # Update helpers (must be globals to be re-usable). @@ -200,21 +201,21 @@ class IMPORT_OT_dxf(bpy.types.Operator): bl_region_type = 'WINDOW' bl_options = {'UNDO'} - filepath = StringProperty( + filepath: StringProperty( name="input file", subtype='FILE_PATH' ) filename_ext = ".dxf" - filter_glob = StringProperty( + filter_glob: StringProperty( default="*.dxf", options={'HIDDEN'}, ) def _update_merge(self, context): _update_import_atts_do(self, context) - merge = BoolProperty( + merge: BoolProperty( name="Merged Objects", description="Merge DXF entities to Blender objects", default=T_Merge, @@ -224,7 +225,7 @@ class IMPORT_OT_dxf(bpy.types.Operator): def _update_merge_options(self, context): _update_import_atts_do(self, context) - merge_options = EnumProperty( + merge_options: EnumProperty( name="Merge", description="Merge multiple DXF entities into one Blender object", items=[('BY_LAYER', "By Layer", "Merge DXF entities of a layer to an object"), @@ -235,37 +236,37 @@ class IMPORT_OT_dxf(bpy.types.Operator): update=_update_merge_options ) - merge_lines = BoolProperty( + merge_lines: BoolProperty( name="Combine LINE entities to polygons", description="Checks if lines are connect on start or end and merges them to a polygon", default=T_MergeLines ) - import_text = BoolProperty( + import_text: BoolProperty( name="Import Text", description="Import DXF Text Entities MTEXT and TEXT", default=T_ImportText, ) - import_light = BoolProperty( + import_light: BoolProperty( name="Import Lights", description="Import DXF Text Entity LIGHT", default=T_ImportLight ) - export_acis = BoolProperty( + export_acis: BoolProperty( name="Export ACIS Entities", description="Export Entities consisting of ACIS code to ACIS .sat/.sab files", default=T_ExportAcis ) - outliner_groups = BoolProperty( + outliner_groups: BoolProperty( name="Display Groups in Outliner(s)", description="Make all outliners in current screen layout show groups", default=T_OutlinerGroups ) - do_bbox = BoolProperty( + do_bbox: BoolProperty( name="Parent Blocks to Bounding Boxes", description="Create a bounding box for blocks with more than one object (faster without)", default=T_Bbox @@ -273,7 +274,7 @@ class IMPORT_OT_dxf(bpy.types.Operator): - block_options = EnumProperty( + block_options: EnumProperty( name="Blocks As", description="Select the representation of DXF blocks: linked objects or group instances", items=[('LINKED_OBJECTS', "Linked Objects", "Block objects get imported as linked objects"), @@ -285,14 +286,14 @@ class IMPORT_OT_dxf(bpy.types.Operator): def _update_create_new_scene(self, context): _update_use_georeferencing_do(self, context) _set_recenter(self, self.recenter) - create_new_scene = BoolProperty( + create_new_scene: BoolProperty( name="Import DXF to new scene", description="Creates a new scene with the name of the imported file", default=T_CreateNewScene, update=_update_create_new_scene, ) - recenter = BoolProperty( + recenter: BoolProperty( name="Center geometry to scene", description="Moves geometry to the center of the scene", default=T_Recenter, @@ -300,14 +301,14 @@ class IMPORT_OT_dxf(bpy.types.Operator): def _update_thickness_width(self, context): _update_import_atts_do(self, context) - represent_thickness_and_width = BoolProperty( + represent_thickness_and_width: BoolProperty( name="Represent line thickness/width", description="Map thickness and width of lines to Bevel objects and extrusion attribute", default=T_ThicknessBevel, update=_update_thickness_width ) - import_atts = BoolProperty( + import_atts: BoolProperty( name="Merge by attributes", description="If 'Merge objects' is on but thickness and width are not chosen to be represented, with this " "option object still can be merged by thickness, with, subd and extrusion attributes " @@ -320,7 +321,7 @@ class IMPORT_OT_dxf(bpy.types.Operator): def _update_use_georeferencing(self, context): _update_use_georeferencing_do(self, context) _set_recenter(self, self.recenter) - use_georeferencing = BoolProperty( + use_georeferencing: BoolProperty( name="Geo Referencing", description="Project coordinates to a given coordinate system or reference point", default=True, @@ -329,7 +330,7 @@ class IMPORT_OT_dxf(bpy.types.Operator): def _update_dxf_indi(self, context): _set_recenter(self, self.recenter) - dxf_indi = EnumProperty( + dxf_indi: EnumProperty( name="DXF coordinate type", description="Indication for spherical or euclidian coordinates", items=[('EUCLIDEAN', "Euclidean", "Coordinates in x/y"), @@ -340,7 +341,7 @@ class IMPORT_OT_dxf(bpy.types.Operator): # Note: FloatProperty is not precise enough, e.g. 1.0 becomes 0.999999999. Python is more precise here (it uses # doubles internally), so we store it as string here and convert to number with py's float() func. - dxf_scale = StringProperty( + dxf_scale: StringProperty( name="Unit Scale", description="Coordinates are assumed to be in meters; deviation must be indicated here", default="1.0" @@ -351,7 +352,7 @@ class IMPORT_OT_dxf(bpy.types.Operator): _set_recenter(self, self.recenter) if PYPROJ: pitems = proj_none_items + proj_user_items + proj_epsg_items - proj_dxf = EnumProperty( + proj_dxf: EnumProperty( name="DXF SRID", description="The coordinate system for the DXF file (check http://epsg.io)", items=pitems, @@ -359,12 +360,12 @@ class IMPORT_OT_dxf(bpy.types.Operator): update=_update_proj, ) - epsg_dxf_user = StringProperty(name="EPSG-Code", default="EPSG") - merc_dxf_lat = FloatProperty(name="Geo-Reference Latitude", default=0.0) - merc_dxf_lon = FloatProperty(name="Geo-Reference Longitude", default=0.0) + epsg_dxf_user: StringProperty(name="EPSG-Code", default="EPSG") + merc_dxf_lat: FloatProperty(name="Geo-Reference Latitude", default=0.0) + merc_dxf_lon: FloatProperty(name="Geo-Reference Longitude", default=0.0) pitems = proj_none_items + ((proj_user_items + proj_tmerc_items + proj_epsg_items) if PYPROJ else proj_tmerc_items) - proj_scene = EnumProperty( + proj_scene: EnumProperty( name="Scn SRID", description="The coordinate system for the Scene (check http://epsg.io)", items=pitems, @@ -372,19 +373,19 @@ class IMPORT_OT_dxf(bpy.types.Operator): update=_update_proj, ) - epsg_scene_user = StringProperty(name="EPSG-Code", default="EPSG") - merc_scene_lat = FloatProperty(name="Geo-Reference Latitude", default=0.0) - merc_scene_lon = FloatProperty(name="Geo-Reference Longitude", default=0.0) + epsg_scene_user: StringProperty(name="EPSG-Code", default="EPSG") + merc_scene_lat: FloatProperty(name="Geo-Reference Latitude", default=0.0) + merc_scene_lon: FloatProperty(name="Geo-Reference Longitude", default=0.0) # internal use only! - internal_using_scene_srid = BoolProperty(default=False, options={'HIDDEN'}) + internal_using_scene_srid: BoolProperty(default=False, options={'HIDDEN'}) def draw(self, context): layout = self.layout scene = context.scene # merge options - layout.label("Merge Options:") + layout.label(text="Merge Options:") box = layout.box() sub = box.row() #sub.enabled = merge_map[self.merge_options] != BY_BLOCKS @@ -397,7 +398,7 @@ class IMPORT_OT_dxf(bpy.types.Operator): box.prop(self, "merge_lines") # general options - layout.label("Line thickness and width:") + layout.label(text="Line thickness and width:") box = layout.box() box.enabled = not merge_map[self.merge_options] == BY_CLOSED_NO_BULGE_POLY box.prop(self, "represent_thickness_and_width") @@ -406,14 +407,14 @@ class IMPORT_OT_dxf(bpy.types.Operator): sub.prop(self, "import_atts") # optional objects - layout.label("Optional Objects:") + layout.label(text="Optional Objects:") box = layout.box() box.prop(self, "import_text") box.prop(self, "import_light") box.prop(self, "export_acis") # view options - layout.label("View Options:") + layout.label(text="View Options:") box = layout.box() box.prop(self, "outliner_groups") box.prop(self, "create_new_scene") @@ -428,13 +429,13 @@ class IMPORT_OT_dxf(bpy.types.Operator): self.draw_pyproj(box, context.scene) if PYPROJ else self.draw_merc(box) def draw_merc(self, box): - box.label("DXF File:") + box.label(text="DXF File:") box.prop(self, "dxf_indi") box.prop(self, "dxf_scale") sub = box.column() sub.enabled = not _recenter_allowed(self) - sub.label("Geo Reference:") + sub.label(text="Geo Reference:") sub = box.column() sub.enabled = not _recenter_allowed(self) if is_ref_scene(bpy.context.scene): @@ -478,26 +479,26 @@ class IMPORT_OT_dxf(bpy.types.Operator): col.alert = True col.prop(self, "epsg_scene_user") col.alert = False - col.label("") # Placeholder. + col.label(text="") # Placeholder. elif self.proj_scene == 'TMERC': col.prop(self, "merc_scene_lat", text="Lat") col.prop(self, "merc_scene_lon", text="Lon") else: - col.label("") # Placeholder. - col.label("") # Placeholder. + col.label(text="") # Placeholder. + col.label(text="") # Placeholder. # user info if self.proj_scene != 'NONE': if not valid_dxf_srid: - box.label("DXF SRID not valid", icon="ERROR") + box.label(text="DXF SRID not valid", icon="ERROR") if self.proj_dxf == 'NONE': - box.label("", icon='ERROR') - box.label("DXF SRID must be set, otherwise") + box.label(text="", icon='ERROR') + box.label(text="DXF SRID must be set, otherwise") if self.proj_scene == 'USER': code = self.epsg_scene_user else: code = self.proj_scene - box.label('Scene SRID %r is ignored!' % code) + box.label(text='Scene SRID %r is ignored!' % code) def execute(self, context): block_map = {"LINKED_OBJECTS": LINKED_OBJECTS, "GROUP_INSTANCES": GROUP_INSTANCES} @@ -558,12 +559,12 @@ def menu_func(self, context): def register(): - bpy.utils.register_module(__name__) + bpy.utils.register_class(IMPORT_OT_dxf) bpy.types.TOPBAR_MT_file_import.append(menu_func) def unregister(): - bpy.utils.unregister_module(__name__) + bpy.utils.unregister_class(IMPORT_OT_dxf) bpy.types.TOPBAR_MT_file_import.remove(menu_func) diff --git a/io_import_dxf/dxfimport/do.py b/io_import_dxf/dxfimport/do.py index 8db6b854..e10d7d70 100644 --- a/io_import_dxf/dxfimport/do.py +++ b/io_import_dxf/dxfimport/do.py @@ -325,22 +325,22 @@ class Do: # turn clockwise if angdir == 0: rot = Matrix.Rotation(radians(-90), 3, "Z") - start = x_vec * radius * Matrix.Rotation(-s, 3, "Z") - end = x_vec * radius * Matrix.Rotation(-e, 3, "Z") + start = x_vec * radius @ Matrix.Rotation(-s, 3, "Z") + end = x_vec * radius @ Matrix.Rotation(-e, 3, "Z") # turn counter-clockwise else: rot = Matrix.Rotation(radians(90), 3, "Z") - start = x_vec * radius * Matrix.Rotation(s, 3, "Z") - end = x_vec * radius * Matrix.Rotation(e, 3, "Z") + start = x_vec * radius @ Matrix.Rotation(s, 3, "Z") + end = x_vec * radius @ Matrix.Rotation(e, 3, "Z") # start spline = list() spline.append(vc + start) if abs(angle) - pi / 2 > threshold: # if angle is more than pi/2 incl. threshold - spline.append(vc + start + start * kappa * rot) + spline.append(vc + start + start * kappa @ rot) else: - spline.append(vc + start + start * kappa * angle / (pi / 2) * rot) + spline.append(vc + start + start * kappa * angle / (pi / 2) @ rot) # fill if angle is larger than 90 degrees a = pi / 2 @@ -348,15 +348,15 @@ class Do: fill = start while abs(angle) - a > threshold: - fillnext = fill * rot + fillnext = fill @ rot spline.append(vc + fillnext + fill * kappa) spline.append(vc + fillnext) # if this was the last fill control point if abs(angle) - a - pi / 2 < threshold: end_angle = (abs(angle) - a) * abs(angle) / angle - spline.append(vc + fillnext + fillnext * kappa * end_angle / (pi / 2) * rot) + spline.append(vc + fillnext + fillnext * kappa * end_angle / (pi / 2) @ rot) else: - spline.append(vc + fillnext + fillnext * kappa * rot) + spline.append(vc + fillnext + fillnext * kappa @ rot) fill = fillnext a += pi / 2 @@ -364,7 +364,7 @@ class Do: end_angle = angle # end - spline.append(vc + end + end * -kappa * end_angle / (pi / 2) * rot) + spline.append(vc + end + end * -kappa * end_angle / (pi / 2) @ rot) spline.append(vc + end) if len(spline) % 3 != 1: @@ -405,9 +405,9 @@ class Do: try: b[0].co = vc + r - b[1].co = vc + r * clockwise - b[2].co = vc + r * clockwise * clockwise - b[3].co = vc + r * clockwise * clockwise * clockwise + b[1].co = vc + r @ clockwise + b[2].co = vc + r @ clockwise @ clockwise + b[3].co = vc + r @ clockwise @ clockwise @ clockwise except: print("Circle center: ", vc, "radius: ", r) raise @@ -444,14 +444,14 @@ class Do: clockwise = Matrix(((0, -1, 0), (1, 0, 0), (0, 0, 1))) if len(major) == 2: major = major.to_3d() - minor = major * en.ratio * clockwise + minor = major * en.ratio @ clockwise lh = b[1].handle_left - b[1].co rh = b[1].handle_right - b[1].co b[1].co = vc + minor b[1].handle_left = b[1].co + lh b[1].handle_right = b[1].co + rh - b[3].co = vc + minor * clockwise * clockwise + b[3].co = vc + minor @ clockwise @ clockwise b[3].handle_left = b[3].co + rh b[3].handle_right = b[3].co + lh @@ -632,7 +632,7 @@ class Do: if entity.dxftype not in {"LINE", "POINT"}: if is_.extrusion(entity): transformation = convert.extrusion_to_matrix(entity) - obj.location = transformation * obj.location + obj.location = transformation @ obj.location obj.rotation_euler.rotate(transformation) def _bbox(self, objects, scene): @@ -643,7 +643,7 @@ class Do: for obj in objects: om = obj.matrix_basis for v in obj.bound_box: - p = om * Vector(v) + p = om @ Vector(v) if p.x < xmin: xmin = p.x if p.x > xmax: @@ -723,7 +723,7 @@ class Do: o = bpy.data.objects.new("Point", None) o.location = self.proj(en.point) self._extrusion(o, en) - scene.objects.link(o) + scene.collection.objects.link(o) group = self._get_group(en.layer) group.objects.link(o) @@ -751,7 +751,7 @@ class Do: o.location = self.proj(en.position) dir = self.proj(en.target) - self.proj(en.position) o.rotation_quaternion = dir.rotation_difference(Vector((0, 0, -1))) - scene.objects.link(o) + scene.collection.objects.link(o) return o def mtext(self, en, scene, name): @@ -830,11 +830,11 @@ class Do: if new_insert.name not in group.objects: group.objects.link(new_insert) if invisible is not None: - new_insert.hide = bool(invisible) + new_insert.hide_viewport = bool(invisible) if inserts is not None: inserts.append(new_insert) new_insert.parent = parent - scene.objects.link(new_insert) + scene.collection.objects.link(new_insert) if name is None: name = entity.name @@ -866,7 +866,7 @@ class Do: if len(insert.children) > 0: i_copy = bpy.data.objects.new(insert.name, None) i_copy.matrix_basis = insert.matrix_basis - scene.objects.link(i_copy) + scene.collection.objects.link(i_copy) group.objects.link(i_copy) kids = insert.children[:] for child in kids: @@ -880,10 +880,10 @@ class Do: if len(objects) > 1 or len(insert_bounding_boxes) > 0: if self.do_bounding_boxes: o = self._object_bbox(objects + insert_bounding_boxes, scene, name, recursion_level == 0) - scene.objects.link(o) + scene.collection.objects.link(o) else: o = bpy.data.objects.new(name, None) - scene.objects.link(o) + scene.collection.objects.link(o) if len(objects) > 0: for obj in objects: obj.parent = o @@ -893,13 +893,13 @@ class Do: else: # strange case but possible according to the testfiles o = bpy.data.objects.new(name, None) - scene.objects.link(o) + scene.collection.objects.link(o) # unlink bounding boxes of inserts for ib in insert_bounding_boxes: if ib.name in group.objects: group.objects.unlink(ib) - scene.objects.unlink(ib) + scene.collection.objects.unlink(ib) # parent inserts to this block before any transformation on the block is being applied for obj in inserts: @@ -918,11 +918,11 @@ class Do: for known_object in known_objects: oc = known_object.copy() - scene.objects.link(oc) + scene.collection.objects.link(oc) objects.append(oc) o = known_o.copy() - scene.objects.link(o) + scene.collection.objects.link(o) _recursive_copy_inserts(o, known_inserts, inserts, group, invisible) @@ -940,7 +940,7 @@ class Do: # visibility if invisible is not None: for obj in objects: - obj.hide = bool(invisible) + obj.hide_viewport = bool(invisible) # block transformations o.location = self.proj(entity.basepoint) @@ -990,14 +990,14 @@ class Do: for i in inserts: sub_group = i.instance_collection - block_scene.objects.unlink(i) + block_scene.collection.objects.unlink(i) block_group.objects.unlink(i) i_empty = bpy.data.objects.new(i.name, None) i_empty.matrix_basis = i.matrix_basis i_empty.instance_type = "COLLECTION" i_empty.instance_collection = sub_group block_group.objects.link(i_empty) - block_scene.objects.link(i_empty) + block_scene.collection.objects.link(i_empty) self.known_blocks[name] = [objects, inserts, bbox] else: @@ -1010,9 +1010,9 @@ class Do: o.instance_collection = block_group group.objects.link(o) if invisible is not None: - o.hide = invisible + o.hide_viewport = invisible o.location = self.proj(entity.basepoint) - scene.objects.link(o) + scene.collection.objects.link(o) # block_scene.update() return o @@ -1079,9 +1079,9 @@ class Do: # visibility if invisible is None: - o.hide = bool(entity.invisible) + o.hide_viewport = bool(entity.invisible) else: - o.hide = bool(invisible) + o.hide_viewport = bool(invisible) # attributes if self.import_text: @@ -1090,7 +1090,7 @@ class Do: # Blender custom property o[a.tag] = a.text attname = entity.name + "_" + a.tag - scene.objects.link(self.text(a, scene, attname)) + scene.collection.objects.link(self.text(a, scene, attname)) return o @@ -1173,7 +1173,7 @@ class Do: bevel = bpy.data.objects.new("BEVEL", bevd) obj.data.bevel_object = bevel - scene.objects.link(bevel) + scene.collection.objects.link(bevel) # CURVE TAPER if has_varying_width and len(ew) == 1: @@ -1195,7 +1195,7 @@ class Do: taper = bpy.data.objects.new("TAPER", tapd) obj.data.taper_object = taper - scene.objects.link(taper) + scene.collection.objects.link(taper) # THICKNESS FOR CURVES HAVING A WIDTH if th != 0: @@ -1233,7 +1233,7 @@ class Do: bm.to_mesh(d) o = bpy.data.objects.new(name, d) - scene.objects.link(o) + scene.collection.objects.link(o) return o def object_mesh(self, entities, scene, name): @@ -1390,7 +1390,7 @@ class Do: if type(o) == bpy.types.Object: if o.name not in scene.objects: - scene.objects.link(o) + scene.collection.objects.link(o) if o.name not in group.objects: group.objects.link(o) @@ -1445,16 +1445,16 @@ class Do: extrusion = convert.extrusion_to_matrix(entity) scale = Matrix(((entity.scale[0],0,0,0),(0,entity.scale[1],0,0),(0,0,entity.scale[2],0),(0,0,0,1))) rotation = radians(entity.rotation) if aunits == 0 else entity.rotation - rotm = scale * extrusion * extrusion.Rotation(rotation, 4, "Z") + rotm = scale @ extrusion @ extrusion.Rotation(rotation, 4, "Z") if location is None: - location = rotm * Vector(entity.insert) + location = rotm @ Vector(entity.insert) entity.insert = (0, 0, 0) transformation = rotm else: - transformation = rotm.Translation((extrusion * Vector(entity.insert))-location) * rotm + transformation = rotm.Translation((extrusion @ Vector(entity.insert))-location) @ rotm verts = [] for v in base: - verts.append(bm.verts.new(transformation * v)) + verts.append(bm.verts.new(transformation @ v)) bm.faces.new(verts) @@ -1463,7 +1463,7 @@ class Do: bm.to_mesh(m) o = bpy.data.objects.new(blockname, m) o.location = location - scene.objects.link(o) + scene.collection.objects.link(o) self._nest_block(o, blockname, blgroup, scene) o.instance_type = "FACES" @@ -1473,7 +1473,7 @@ class Do: def _nest_block(self, parent, name, blgroup, scene): b = self.dwg.blocks[name] e = bpy.data.objects.new(name, None) - scene.objects.link(e) + scene.collection.objects.link(e) #e.location = parent.location e.parent = parent for TYPE, grouped in groupsort.by_dxftype(b): @@ -1639,7 +1639,7 @@ class Do: elif self.pScene is not None: # assume Proj scene['SRID'] = re.findall("\+init=(.+)\s", self.pScene.srs)[0] - bpy.context.screen.scene = scene + #bpy.context.screen.scene = scene return self.errors # trying to import dimensions: -- cgit v1.2.3