Upstream: https://github.com/Rhoban/onshape-to-robot Upstream-Commit: 80e710700aac9573a2230f74f7ce9e094833a0bc Upstream-Branch: master
158 lines
5.9 KiB
Python
158 lines
5.9 KiB
Python
def main():
|
|
import numpy as np
|
|
import math
|
|
import commentjson as json
|
|
import os
|
|
import sys, os
|
|
from dotenv import load_dotenv, find_dotenv
|
|
from colorama import Fore, Back, Style
|
|
|
|
load_dotenv(find_dotenv(usecwd=True))
|
|
|
|
if len(sys.argv) < 2:
|
|
print("Usage: onshape-to-robot-pure-shape {STL file} [prefix=PureShapes]")
|
|
else:
|
|
fileName = sys.argv[1]
|
|
robotDir = os.path.dirname(fileName)
|
|
configFile = os.path.join(robotDir, "config.json")
|
|
prefix = "PureShapes"
|
|
if len(sys.argv) > 2:
|
|
prefix = sys.argv[2]
|
|
|
|
from .onshape_api.client import Client
|
|
|
|
client = Client(logging=False, creds=configFile)
|
|
|
|
parts = fileName.split(".")
|
|
parts[-1] = "part"
|
|
partFileName = ".".join(parts)
|
|
parts[-1] = "scad"
|
|
scadFileName = ".".join(parts)
|
|
|
|
with open(partFileName, "r", encoding="utf-8") as stream:
|
|
part = json.load(stream)
|
|
partid = part["partId"]
|
|
result = client.get_sketches(
|
|
part["documentId"],
|
|
part["documentMicroversion"],
|
|
part["elementId"],
|
|
part["configuration"],
|
|
)
|
|
|
|
scad = '% scale(1000) import("' + os.path.basename(fileName) + '");\n'
|
|
|
|
sketchDatas = []
|
|
for sketch in result["sketches"]:
|
|
if sketch["sketch"].startswith(prefix):
|
|
parts = sketch["sketch"].split(" ")
|
|
if len(parts) >= 2:
|
|
sketch["thickness"] = float(parts[1])
|
|
else:
|
|
print(
|
|
Fore.RED
|
|
+ 'ERROR: The sketch name should contain extrusion size (e.g "PureShapes 5.3")'
|
|
+ Style.RESET_ALL
|
|
)
|
|
exit(0)
|
|
sketchDatas.append(sketch)
|
|
|
|
if len(sketchDatas):
|
|
print(
|
|
Fore.GREEN
|
|
+ "* Found "
|
|
+ str(len(sketchDatas))
|
|
+ " PureShapes sketches"
|
|
+ Style.RESET_ALL
|
|
)
|
|
for sketchData in sketchDatas:
|
|
# Retrieving sketch transform matrix
|
|
m = sketchData["transformMatrix"]
|
|
mm = [m[0:4], m[4:8], m[8:12], m[12:16]]
|
|
mm[0][3] *= 1000
|
|
mm[1][3] *= 1000
|
|
mm[2][3] *= 1000
|
|
scad += "\n"
|
|
scad += "// Sketch " + sketchData["sketch"] + "\n"
|
|
scad += "multmatrix(" + str(mm) + ") {" + "\n"
|
|
scad += "thickness = %f;\n" % sketchData["thickness"]
|
|
scad += "translate([0, 0, -thickness]) {\n"
|
|
|
|
boxes = {}
|
|
|
|
def boxSet(id, pointName, point):
|
|
if id not in boxes:
|
|
boxes[id] = {}
|
|
boxes[id][pointName] = point
|
|
|
|
for entry in sketchData["geomEntities"]:
|
|
if entry["entityType"] == "circle":
|
|
center = entry["center"]
|
|
scad += " translate([%f, %f, 0]) {\n" % (
|
|
center[0] * 1000,
|
|
center[1] * 1000,
|
|
)
|
|
scad += " cylinder(r=%f,h=thickness);\n" % (
|
|
entry["radius"] * 1000
|
|
)
|
|
scad += " }\n"
|
|
if entry["entityType"] == "point":
|
|
parts = entry["id"].split(".")
|
|
if len(parts) == 3:
|
|
if parts[1] == "top" and parts[2] == "start":
|
|
boxSet(parts[0], "A", entry["point"])
|
|
if parts[1] == "top" and parts[2] == "end":
|
|
boxSet(parts[0], "B", entry["point"])
|
|
if parts[1] == "bottom" and parts[2] == "start":
|
|
boxSet(parts[0], "C", entry["point"])
|
|
if parts[1] == "bottom" and parts[2] == "end":
|
|
boxSet(parts[0], "D", entry["point"])
|
|
|
|
for id in boxes:
|
|
if len(boxes[id]) == 4:
|
|
A, B = np.array(boxes[id]["A"]), np.array(boxes[id]["B"])
|
|
C, D = np.array(boxes[id]["C"]), np.array(boxes[id]["D"])
|
|
AB = B - A
|
|
|
|
# Making sure that the orientation of the square is correct
|
|
AB90 = np.array([-AB[1], AB[0]])
|
|
side = AB90.dot(C - A)
|
|
width = np.linalg.norm(B - A)
|
|
height = np.linalg.norm(B - D)
|
|
if side < 0:
|
|
A, B, C, D = C, D, A, B
|
|
|
|
AB = B - A
|
|
alpha = np.rad2deg(math.atan2(AB[1], AB[0]))
|
|
scad += " translate([%f, %f, 0]) {\n" % (
|
|
A[0] * 1000,
|
|
A[1] * 1000,
|
|
)
|
|
scad += " rotate([0, 0, " + str(alpha) + "]) {" + "\n"
|
|
scad += " cube([%f, %f, thickness]);\n" % (
|
|
width * 1000,
|
|
height * 1000,
|
|
)
|
|
scad += " }\n"
|
|
scad += " }\n"
|
|
|
|
scad += "}\n"
|
|
scad += "}\n"
|
|
|
|
with open(scadFileName, "w", encoding="utf-8") as stream:
|
|
stream.write(scad)
|
|
|
|
directory = os.path.dirname(fileName)
|
|
os.system(
|
|
"cd " + directory + "; openscad " + os.path.basename(scadFileName)
|
|
)
|
|
else:
|
|
print(
|
|
Fore.RED
|
|
+ "ERROR: Can't find pure shape sketch in this part"
|
|
+ Style.RESET_ALL
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|