mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-05 21:13:58 -06:00
Added plugin for reading cad files with .step file extension
CURA-4891
This commit is contained in:
parent
a4455bbbe5
commit
0cebc2e9f3
4 changed files with 208 additions and 0 deletions
109
plugins/STEPReader/StepReader.py
Normal file
109
plugins/STEPReader/StepReader.py
Normal 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()
|
20
plugins/STEPReader/__init__.py
Normal file
20
plugins/STEPReader/__init__.py
Normal 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() }
|
8
plugins/STEPReader/plugin.json
Normal file
8
plugins/STEPReader/plugin.json
Normal 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
71
plugins/STEPReader/stl.py
Normal 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)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue