Hello Everyone,
The following step files are the same part. Now I pulled it into Rhino and just re-exported it. What I noticed is that what were lines in the SolidWorks export become curves (even though they are perfectly straight). Probably in most cases not a problem, but in this case it breaks the import in third-party software for sheet metal processing.
To my question. Is there an option to export it so that real lines stay lines in the step export?
RhinoPart.stp (33.6 KB)
SolidPart.step (26.6 KB)
Fixed it with a post-processor script, but I’d rather have it Rhinonative.
"""Export selected objects as a STEP file.
Run inside Rhino: _-RunPythonScript "<path>/StepExport.py"
Exports via Rhino's STEP writer, then rewrites the file in place:
- degree-1 B_SPLINE_CURVE_WITH_KNOTS (2 ctrl pts) -> LINE
- TRIMMED_CURVE -> direct reference to basis curve
Targets importers that reject spline-encoded straight edges and trimmed-curve
wrappers. Requires "Split closed surfaces" OFF in the STEP export options.
"""
import re, math, io
import Rhino
import scriptcontext as sc
def fix_step(path):
txt = io.open(path, "r", encoding="ascii", errors="ignore").read()
recs, order = {}, []
for m in re.finditer(r"#(\d+)=(.*?);\s*?\n", txt, re.S):
recs[int(m.group(1))] = m.group(2).strip()
order.append(int(m.group(1)))
maxid = [max(recs)]
def nextid():
maxid[0] += 1
return maxid[0]
def cart(pid):
m = re.search(r"CARTESIAN_POINT\('[^']*',\(([^)]*)\)\)", recs[pid])
return [float(x) for x in m.group(1).split(",")]
replaced, new_entities, redirect = 0, {}, {}
for eid in order:
body = recs[eid]
if body.startswith("B_SPLINE_CURVE_WITH_KNOTS"):
m = re.match(r"B_SPLINE_CURVE_WITH_KNOTS\('[^']*',(\d+),\(([^)]*)\)", body)
if not m or m.group(1) != "1":
continue
pts = [int(x.strip()[1:]) for x in m.group(2).split(",")]
if len(pts) != 2:
continue
p0, p1 = cart(pts[0]), cart(pts[1])
d = [b - a for a, b in zip(p0, p1)]
L = math.sqrt(sum(x * x for x in d))
if L == 0:
continue
did = nextid()
new_entities[did] = "DIRECTION('',(%s))" % ",".join(repr(x / L) for x in d)
vid = nextid()
new_entities[vid] = "VECTOR('',#%d,%r)" % (did, L)
recs[eid] = "LINE('',#%d,#%d)" % (pts[0], vid)
replaced += 1
elif body.startswith("TRIMMED_CURVE"):
m = re.match(r"TRIMMED_CURVE\(.?.?,#(\d+),", body)
if m:
redirect[eid] = int(m.group(1))
refpat = re.compile(r"#(\d+)")
def sub(m):
i = int(m.group(1))
return "#%d" % redirect[i] if i in redirect else m.group(0)
for eid in order:
if eid not in redirect and "#" in recs[eid]:
recs[eid] = refpat.sub(sub, recs[eid])
for eid in redirect:
del recs[eid]
head, tail = txt.split("DATA;", 1)
_, endsec = tail.rsplit("ENDSEC;", 1)
out = [head + "DATA;\n"]
for eid in order:
if eid in recs:
out.append("#%d=%s;\n" % (eid, recs[eid]))
for eid in sorted(new_entities):
out.append("#%d=%s;\n" % (eid, new_entities[eid]))
out.append("ENDSEC;" + endsec)
io.open(path, "w", encoding="ascii", newline="\n").write(u"".join(out))
return replaced, len(redirect)
def main():
doc = sc.doc
if doc.Objects.GetSelectedObjects(False, False) is None or \
not any(True for _ in doc.Objects.GetSelectedObjects(False, False)):
Rhino.RhinoApp.WriteLine("StepExport: select the object(s) first.")
return
fd = Rhino.UI.SaveFileDialog()
fd.Filter = "STEP files (*.stp)|*.stp"
fd.DefaultExt = "stp"
fd.Title = "Export STEP"
if not fd.ShowSaveDialog():
return
path = fd.FileName
ok = Rhino.RhinoApp.RunScript('_-Export "%s" _Enter _Enter _Enter' % path, False)
import os
if not ok or not os.path.exists(path):
Rhino.RhinoApp.WriteLine("StepExport: export failed.")
return
lines, trims = fix_step(path)
Rhino.RhinoApp.WriteLine(
"StepExport: %s (%d splines -> LINE, %d trimmed curves unwrapped)"
% (path, lines, trims))
main()
Best, and thanks in advance!
Felix
