Added plugin for reading cad files with .step file extension

CURA-4891
This commit is contained in:
Aleksei S 2018-02-14 14:03:57 +01:00
parent a4455bbbe5
commit 0cebc2e9f3
4 changed files with 208 additions and 0 deletions

View file

@ -0,0 +1,109 @@
# Copyright (c) 2018 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher.
from UM.Mesh.MeshReader import MeshReader
from UM.Mesh.MeshBuilder import MeshBuilder
from UM.Logger import Logger
from UM.Scene.SceneNode import SceneNode
from UM.Job import Job
from os.path import abspath, join, dirname
import OCC.GProp
import OCC.BRepGProp
import OCC.BRep
import OCC.IFSelect
import OCC.Interface
import OCC.STEPControl
import OCC.TopoDS
import OCC.BRepBuilderAPI
import OCC.gp
import OCC.TopoDS
from OCC.gp import gp_Pnt
from .stl import StlExporter
from aocutils.analyze.bounds import BoundingBox
class STEPReader(MeshReader):
def __init__(self):
super(STEPReader, self).__init__()
self._supported_extensions = [".step"]
def read(self, file_name):
mesh_builder = MeshBuilder()
mesh_builder.setFileName(file_name)
scene_node = SceneNode()
self._shapes = list()
stepcontrol_reader = OCC.STEPControl.STEPControl_Reader()
status = stepcontrol_reader.ReadFile(file_name)
if status == OCC.IFSelect.IFSelect_RetDone:
stepcontrol_reader.PrintCheckLoad(False, OCC.IFSelect.IFSelect_ItemsByEntity)
nb_roots = stepcontrol_reader.NbRootsForTransfer()
if nb_roots == 0:
return None
stepcontrol_reader.PrintCheckTransfer(False, OCC.IFSelect.IFSelect_ItemsByEntity)
self._number_of_shapes = stepcontrol_reader.NbShapes()
for n in range(1, nb_roots + 1):
ok = stepcontrol_reader.TransferRoot(n)
if ok:
a_shape = stepcontrol_reader.Shape(n)
if a_shape.IsNull():
return None
else:
self._shapes.append(a_shape)
step_ = abspath(join(dirname(__file__), "./test_model.stl"))
self.shape_to_stl(a_shape, step_, scale=1., ascii_mode_=True, factor_=4000., use_min_dim_=False)
return scene_node
def shape_to_stl(self, shape_, stl_file_, scale, ascii_mode_, factor_, use_min_dim_):
exporter = StlExporter(filename=stl_file_, ascii_mode=ascii_mode_)
shape_ = self.scale_uniform(shape_, gp_Pnt(0, 0, 0), scale, False)
self.createMesh(shape_, factor=factor_, use_min_dim=use_min_dim_)
exporter.set_shape(shape_)
exporter.write_file()
def initSceneNode(self, m_shape):
print()
def createMesh(self,shape, factor=4000., use_min_dim=False):
bb = BoundingBox(shape)
if use_min_dim:
linear_deflection = bb.min_dimension / factor
OCC.BRepMesh.BRepMesh_IncrementalMesh(shape, linear_deflection)
else:
linear_deflection = bb.max_dimension / factor
OCC.BRepMesh.BRepMesh_IncrementalMesh(shape, linear_deflection)
def scale_uniform(self, brep, pnt, factor, copy=False):
trns = OCC.gp.gp_Trsf()
trns.SetScale(pnt, factor)
brep_trns = OCC.BRepBuilderAPI.BRepBuilderAPI_Transform(brep, trns, copy)
brep_trns.Build()
return brep_trns.Shape()

View file

@ -0,0 +1,20 @@
# Copyright (c) 2018 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher.
from . import StepReader
from UM.i18n import i18nCatalog
i18n_catalog = i18nCatalog("uranium")
def getMetaData():
return {
"mesh_reader": [
{
"extension": "step",
"description": i18n_catalog.i18nc("@item:inlistbox", "STEP File")
}
]
}
def register(app):
return { "mesh_reader": StepReader.STEPReader() }

View file

@ -0,0 +1,8 @@
{
"name": "STEP Reader",
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for reading STEP files.",
"api": 4,
"i18n-catalog": "uranium"
}

71
plugins/STEPReader/stl.py Normal file
View file

@ -0,0 +1,71 @@
from __future__ import print_function
import logging
import OCC.StlAPI
import OCC.TopoDS
import aocxchange.exceptions
import aocxchange.extensions
import aocxchange.utils
import aocxchange.checks
logger = logging.getLogger(__name__)
class StlImporter(object):
def __init__(self, filename):
logger.info("StlImporter instantiated with filename : %s" % filename)
aocxchange.checks.check_importer_filename(filename, aocxchange.extensions.stl_extensions)
self._filename = filename
self._shape = None
logger.info("Reading file ....")
self.read_file()
def read_file(self):
stl_reader = OCC.StlAPI.StlAPI_Reader()
shape = OCC.TopoDS.TopoDS_Shape()
print(self._filename)
stl_reader.Read(shape, self._filename)
self._shape = shape
@property
def shape(self):
r"""Shape"""
if self._shape.IsNull():
raise AssertionError("Error: the shape is NULL")
else:
return self._shape
class StlExporter(object):
def __init__(self, filename=None, ascii_mode=False):
logger.info("StlExporter instantiated with filename : %s" % filename)
logger.info("StlExporter ascii : %s" % str(ascii_mode))
aocxchange.checks.check_exporter_filename(filename,
aocxchange.extensions.stl_extensions)
aocxchange.checks.check_overwrite(filename)
self._shape = None # only one shape can be exported
self._ascii_mode = ascii_mode
self._filename = filename
def set_shape(self, a_shape):
aocxchange.checks.check_shape(a_shape)
self._shape = a_shape
def write_file(self):
stl_writer = OCC.StlAPI.StlAPI_Writer()
try:
stl_writer.Write(self._shape, self._filename, self._ascii_mode)
except TypeError:
stl_writer.SetASCIIMode(self._ascii_mode)
stl_writer.Write(self._shape, self._filename)