diff --git a/kibot/EasyEDA/easyeda_3d.py b/kibot/EasyEDA/easyeda_3d.py index 91bfae47..d4203f22 100644 --- a/kibot/EasyEDA/easyeda_3d.py +++ b/kibot/EasyEDA/easyeda_3d.py @@ -20,6 +20,11 @@ API_ENDPOINT = "https://easyeda.com/api/products/{lcsc_id}/components?version=6. ENDPOINT_3D_MODEL = "https://easyeda.com/analyzer/api/3dmodel/{uuid}" VRML_HEADER = "#VRML V2.0 utf8\n# 3D model generated by KiBot (using easyeda2kicad.py code)\n" USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0" +# From https://github.com/TousstNicolas/JLC2KiCad_lib/blob/master/JLC2KiCadLib/footprint/model3d.py +# `qAxj6KHrDKw4blvCG8QJPs7Y` is a constant in +# https://modules.lceda.cn/smt-gl-engine/0.8.22.6032922c/smt-gl-engine.js +# and points to the bucket containing the step files. +ENDPOINT_STEP = "https://modules.easyeda.com/qAxj6KHrDKw4blvCG8QJPs7Y/{uuid}" # KiCad materials that we try to detect MATERIAL_PIN_01 = {"name": 'PIN-01', "ambient_intensity": 0.271, "shininess": 0.7, "transparency": 0, "diffuse_color": ('0.824', '0.820', '0.781'), "specular_color": ('0.328', '0.258', '0.172')} @@ -55,11 +60,25 @@ class EasyedaApi: return cp_cad_info["result"] def get_raw_3d_model_obj(self, uuid): - r = requests.get(url=ENDPOINT_3D_MODEL.format(uuid=uuid), headers={"User-Agent": self.headers["User-Agent"]}) + # Surface model + url = ENDPOINT_3D_MODEL.format(uuid=uuid) + logger.debugl(3, f"- Downloading raw 3D model from {url}") + r = requests.get(url=url, headers={"User-Agent": self.headers["User-Agent"]}) if r.status_code != requests.codes.ok: logger.warning(W_EEDA3D+"Failed to download 3D model data found for EasyEDA uuid: "+uuid) - return None - return r.content.decode() + obj = None + else: + obj = r.content.decode() + # 3D object + url = ENDPOINT_STEP.format(uuid=uuid) + logger.debugl(3, f"- Downloading STEP 3D model from {url}") + r = requests.get(url=url, headers={"User-Agent": self.headers["User-Agent"]}) + if r.status_code != requests.codes.ok: + logger.warning(W_EEDA3D+"Failed to download STEP 3D model data found for EasyEDA uuid: "+uuid) + step = None + else: + step = r.content.decode() + return obj, step def convert_to_mm(dim: float): @@ -85,6 +104,7 @@ class Ee3dModel: translation: Ee3dModelBase rotation: Ee3dModelBase raw_obj: str = None + step: str = None def convert_to_mm(self) -> None: self.translation.convert_to_mm() @@ -119,7 +139,7 @@ class Easyeda3dModelImporter: if model_3d_info: model_3d = self.parse_3d_model_info(info=model_3d_info) if self.download_raw_3d_model: - model_3d.raw_obj = EasyedaApi().get_raw_3d_model_obj(uuid=model_3d.uuid) + model_3d.raw_obj, model_3d.step = EasyedaApi().get_raw_3d_model_obj(uuid=model_3d.uuid) return model_3d logger.warning(W_EEDA3D+"No 3D model available for `{}`".format(lcsc_id)) @@ -300,16 +320,29 @@ class Exporter3dModelKicad: def __init__(self, model_3d): self.input = model_3d self.output = generate_wrl_model(model_3d=model_3d) if model_3d and model_3d.raw_obj else None + self.output_step = model_3d.step if model_3d and model_3d.step else None def export(self, lib_path, fname=None): - if self.output is None: - return None - if fname is None: - fname = self.output.name+'.wrl' - fname = os.path.join(lib_path, fname) - with open(fname, "w", encoding="utf-8") as my_lib: - my_lib.write(self.output.raw_wrl) - return fname + name_wrl = name_step = None + # Export the WRL + if self.output is not None: + name_wrl = fname + if name_wrl is None: + name_wrl = self.output.name+'.wrl' + name_wrl = os.path.join(lib_path, name_wrl) + with open(name_wrl, "w", encoding="utf-8") as my_lib: + my_lib.write(self.output.raw_wrl) + # Export the STEP + if self.output_step is not None: + name_step = fname + if name_step is None: + name_step = (self.output.name if self.output else self.input.uuid)+'.step' + else: + name_step = os.path.splitext(name_step)[0]+'.step' + name_step = os.path.join(lib_path, name_step) + with open(name_step, "w", encoding="utf-8") as my_lib: + my_lib.write(self.output_step) + return name_wrl or name_step def download_easyeda_3d_model(lcsc_id, dest_path, fname=None):