mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-21 00:51:48 -06:00
Add SolidWorks plugin
CURA-3823
This commit is contained in:
parent
439f3e5029
commit
1c39c90494
13 changed files with 1566 additions and 0 deletions
231
plugins/CuraSolidWorksPlugin/SolidWorksReader.py
Normal file
231
plugins/CuraSolidWorksPlugin/SolidWorksReader.py
Normal file
|
@ -0,0 +1,231 @@
|
|||
# Copyright (c) 2017 Thomas Karl Pietrowski
|
||||
|
||||
# TODOs:
|
||||
# * Adding selection to separately import parts from an assembly
|
||||
|
||||
# Buildings
|
||||
import math
|
||||
|
||||
# Uranium/Cura
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Message import Message
|
||||
from UM.Logger import Logger
|
||||
from UM.Math.Vector import Vector
|
||||
from UM.Math.Quaternion import Quaternion
|
||||
from UM.Mesh.MeshReader import MeshReader
|
||||
|
||||
# Our plugin
|
||||
from .CommonComReader import CommonCOMReader
|
||||
from .SolidWorksConstants import SolidWorksEnums
|
||||
from .SolidWorksReaderUI import SolidWorksReaderUI
|
||||
|
||||
i18n_catalog = i18nCatalog("CuraSolidWorksIntegrationPlugin")
|
||||
|
||||
|
||||
class SolidWorksReader(CommonCOMReader):
|
||||
def __init__(self):
|
||||
super().__init__("SldWorks.Application", "SolidWorks")
|
||||
|
||||
self._extension_part = ".SLDPRT"
|
||||
self._extension_assembly = ".SLDASM"
|
||||
self._supported_extensions = [self._extension_part.lower(),
|
||||
self._extension_assembly.lower(),
|
||||
]
|
||||
|
||||
self._convert_assembly_into_once = True # False is not implemented now!
|
||||
self._file_formats_first_choice = []
|
||||
self._revision = None
|
||||
self._revision_major = None
|
||||
self._revision_minor = None
|
||||
self._revision_patch = None
|
||||
|
||||
self._ui = SolidWorksReaderUI()
|
||||
self._selected_quality = None
|
||||
self._quality_value_map = {"coarse": SolidWorksEnums.swSTLQuality_e.swSTLQuality_Coarse,
|
||||
"find": SolidWorksEnums.swSTLQuality_e.swSTLQuality_Fine}
|
||||
|
||||
self.root_component = None
|
||||
|
||||
def preRead(self, file_name, *args, **kwargs):
|
||||
self._ui.showConfigUI()
|
||||
self._ui.waitForUIToClose()
|
||||
|
||||
if self._ui.getCancelled():
|
||||
return MeshReader.PreReadResult.cancelled
|
||||
|
||||
# get quality
|
||||
self._selected_quality = self._ui.quality
|
||||
if self._selected_quality is None:
|
||||
self._selected_quality = "fine"
|
||||
self._selected_quality = self._selected_quality.lower()
|
||||
|
||||
# give actual value for quality
|
||||
self._selected_quality = self._quality_value_map.get(self._selected_quality,
|
||||
SolidWorksEnums.swSTLQuality_e.swSTLQuality_Fine)
|
||||
|
||||
return MeshReader.PreReadResult.accepted
|
||||
|
||||
def setAppVisible(self, state, **options):
|
||||
options["app_instance"].Visible = state
|
||||
|
||||
def getAppVisible(self, state, **options):
|
||||
return options["app_instance"].Visible
|
||||
|
||||
def startApp(self, visible=False):
|
||||
app_instance = super().startApp(visible = visible)
|
||||
|
||||
# Getting revision after starting
|
||||
revision_number = app_instance.RevisionNumber()
|
||||
Logger.log("d", "SolidWorks RevisionNumber: %s", revision_number)
|
||||
self._revision = [int(x) for x in revision_number.split(".")]
|
||||
self._revision_major = self._revision[0]
|
||||
self._revision_minor = self._revision[1]
|
||||
self._revision_patch = self._revision[2]
|
||||
|
||||
# Re-generate a list of preferred file formats
|
||||
self.updateFormatsFirstChoise()
|
||||
|
||||
return app_instance
|
||||
|
||||
def updateFormatsFirstChoise(self):
|
||||
self._file_formats_first_choice = ["stl"]
|
||||
if self._revision_major >= 25 and "3mf" in self._reader_for_file_format.keys():
|
||||
self._file_formats_first_choice.insert(0, "3mf")
|
||||
|
||||
return self._file_formats_first_choice
|
||||
|
||||
def checkApp(self, **options):
|
||||
functions_to_be_checked = ("OpenDoc", "CloseDoc")
|
||||
for func in functions_to_be_checked:
|
||||
try:
|
||||
getattr(options["app_instance"], func)
|
||||
except:
|
||||
Logger.logException("e", "Error which occurred when checking for a valid app instance")
|
||||
return False
|
||||
return True
|
||||
|
||||
def closeApp(self, **options):
|
||||
if "app_instance" in options.keys():
|
||||
del options["app_instance"]
|
||||
|
||||
def walkComponentsInAssembly(self, root = None):
|
||||
if root is None:
|
||||
root = self.root_component
|
||||
|
||||
children = root.GetChildren
|
||||
|
||||
if children:
|
||||
children = [self.walkComponentsInAssembly(child) for child in children]
|
||||
return root, children
|
||||
else:
|
||||
return root
|
||||
|
||||
"""
|
||||
models = options["sw_model"].GetComponents(True)
|
||||
|
||||
for model in models:
|
||||
#Logger.log("d", model.GetModelDoc2())
|
||||
#Logger.log("d", repr(model.GetTitle))
|
||||
Logger.log("d", repr(model.GetPathName))
|
||||
#Logger.log("d", repr(model.GetType))
|
||||
if model.GetPathName in ComponentsCount.keys():
|
||||
ComponentsCount[model.GetPathName] = ComponentsCount[model.GetPathName] + 1
|
||||
else:
|
||||
ComponentsCount[model.GetPathName] = 1
|
||||
|
||||
for key in ComponentsCount.keys():
|
||||
Logger.log("d", "Found %s %s-times in the assembly!" %(key, ComponentsCount[key]))
|
||||
"""
|
||||
|
||||
def openForeignFile(self, **options):
|
||||
if options["foreignFormat"].upper() == self._extension_part:
|
||||
filetype = SolidWorksEnums.FileTypes.SWpart
|
||||
elif options["foreignFormat"].upper() == self._extension_assembly:
|
||||
filetype = SolidWorksEnums.FileTypes.SWassembly
|
||||
else:
|
||||
raise NotImplementedError("Unknown extension. Something went terribly wrong!")
|
||||
|
||||
#options["sw_model"] = options["app_instance"].OpenDoc(options["foreignFile"], filetype)
|
||||
documentSpecification = options["app_instance"].GetOpenDocSpec(options["foreignFile"])
|
||||
|
||||
## NOTE: SPEC: FileName
|
||||
#documentSpecification.FileName
|
||||
|
||||
## NOTE: SPEC: DocumentType
|
||||
## TODO: Really needed here?!
|
||||
documentSpecification.DocumentType = filetype
|
||||
|
||||
## TODO: Test the impact of LightWeight = True
|
||||
#documentSpecification.LightWeight = True
|
||||
documentSpecification.Silent = True
|
||||
|
||||
## TODO: Double check, whether file was really opened read-only..
|
||||
documentSpecification.ReadOnly = True
|
||||
|
||||
options["sw_model"] = options["app_instance"].OpenDoc7(documentSpecification._comobj)
|
||||
|
||||
if documentSpecification.Warning:
|
||||
Logger.log("w", "Warnings happened while opening your SolidWorks file!")
|
||||
if documentSpecification.Error:
|
||||
Logger.log("e", "Errors happened while opening your SolidWorks file!")
|
||||
error_message = Message(i18n_catalog.i18nc("@info:status", "Errors appeared while opening your SolidWorks file! \
|
||||
Please check, whether it is possible to open your file in SolidWorks itself without any problems as well!" % (self._app_friendly_name)))
|
||||
error_message.show()
|
||||
|
||||
# Might be useful in the future, but no need for this ATM
|
||||
#self.configuration = self.model.getActiveConfiguration
|
||||
#self.root_component = self.configuration.GetRootComponent
|
||||
|
||||
## EXPERIMENTAL: Browse single parts in assembly
|
||||
#if filetype == SolidWorksEnums.FileTypes.SWassembly:
|
||||
# Logger.log("d", 'walkComponentsInAssembly: ' + repr(self.walkComponentsInAssembly()))
|
||||
|
||||
return options
|
||||
|
||||
def exportFileAs(self, **options):
|
||||
if options["tempType"] == "stl":
|
||||
if options["foreignFormat"].upper() == self._extension_assembly:
|
||||
# Backing up current setting of swSTLComponentsIntoOneFile
|
||||
swSTLComponentsIntoOneFileBackup = options["app_instance"].GetUserPreferenceToggle(SolidWorksEnums.UserPreferences.swSTLComponentsIntoOneFile)
|
||||
options["app_instance"].SetUserPreferenceToggle(SolidWorksEnums.UserPreferences.swSTLComponentsIntoOneFile, self._convert_assembly_into_once)
|
||||
|
||||
swExportSTLQualityBackup = options["app_instance"].GetUserPreferenceIntegerValue(SolidWorksEnums.swUserPreferenceIntegerValue_e.swExportSTLQuality)
|
||||
options["app_instance"].SetUserPreferenceIntegerValue(SolidWorksEnums.swUserPreferenceIntegerValue_e.swExportSTLQuality, SolidWorksEnums.swSTLQuality_e.swSTLQuality_Fine)
|
||||
|
||||
# Changing the default unit for STLs to mm, which is expected by Cura
|
||||
swExportStlUnitsBackup = options["app_instance"].GetUserPreferenceIntegerValue(SolidWorksEnums.swUserPreferenceIntegerValue_e.swExportStlUnits)
|
||||
options["app_instance"].SetUserPreferenceIntegerValue(SolidWorksEnums.swUserPreferenceIntegerValue_e.swExportStlUnits, SolidWorksEnums.swLengthUnit_e.swMM)
|
||||
|
||||
# Changing the output type temporary to binary
|
||||
swSTLBinaryFormatBackup = options["app_instance"].GetUserPreferenceToggle(SolidWorksEnums.swUserPreferenceToggle_e.swSTLBinaryFormat)
|
||||
options["app_instance"].SetUserPreferenceToggle(SolidWorksEnums.swUserPreferenceToggle_e.swSTLBinaryFormat, True)
|
||||
|
||||
options["sw_model"].SaveAs(options["tempFile"])
|
||||
|
||||
if options["tempType"] == "stl":
|
||||
# Restoring swSTLBinaryFormat
|
||||
options["app_instance"].SetUserPreferenceToggle(SolidWorksEnums.swUserPreferenceToggle_e.swSTLBinaryFormat, swSTLBinaryFormatBackup)
|
||||
|
||||
# Restoring swExportStlUnits
|
||||
options["app_instance"].SetUserPreferenceIntegerValue(SolidWorksEnums.swUserPreferenceIntegerValue_e.swExportStlUnits, swExportStlUnitsBackup)
|
||||
|
||||
# Restoring swSTLQuality_Fine
|
||||
options["app_instance"].SetUserPreferenceIntegerValue(SolidWorksEnums.swUserPreferenceIntegerValue_e.swExportSTLQuality, swExportSTLQualityBackup)
|
||||
|
||||
if options["foreignFormat"].upper() == self._extension_assembly:
|
||||
# Restoring swSTLComponentsIntoOneFile
|
||||
options["app_instance"].SetUserPreferenceToggle(SolidWorksEnums.UserPreferences.swSTLComponentsIntoOneFile, swSTLComponentsIntoOneFileBackup)
|
||||
|
||||
def closeForeignFile(self, **options):
|
||||
options["app_instance"].CloseDoc(options["foreignFile"])
|
||||
|
||||
def areReadersAvailable(self):
|
||||
return bool(self._reader_for_file_format)
|
||||
|
||||
def nodePostProcessing(self, node):
|
||||
if self._revision_major == 24: # Known problem under SolidWorks 2016: Exported models are rotated by -90 degrees. This rotates it back!
|
||||
rotation = Quaternion.fromAngleAxis(math.radians(90), Vector.Unit_X)
|
||||
node.rotate(rotation)
|
||||
return node
|
||||
|
||||
## Decide if we need to use ascii or binary in order to read file
|
Loading…
Add table
Add a link
Reference in a new issue