Skip to content

Instantly share code, notes, and snippets.

@hyrodium
Last active March 29, 2025 15:54
using BasicBSpline
using BasicBSpline: _vec
using StaticArrays
function parenthesize(v::AbstractVector)
"("*join([string(e) for e in v], ",")*")"
end
function parenthesize(m::AbstractMatrix)
parenthesize([parenthesize(m[i,:]) for i in axes(m, 1)])
end
function generate_step_script(M::BSplineManifold{3})
generate_step_script(RationalBSplineManifold(M))
end
function generate_step_script(M::RationalBSplineManifold{3})
P1, P2, P3 = bsplinespaces(M)
t1_min, t1_max = extrema(domain(P1))
t2_min, t2_max = extrema(domain(P2))
t3_min, t3_max = extrema(domain(P3))
vertices = [
M(t1_min, t2_min, t3_min),
M(t1_min, t2_min, t3_max),
M(t1_min, t2_max, t3_min),
M(t1_min, t2_max, t3_max),
M(t1_max, t2_min, t3_min),
M(t1_max, t2_min, t3_max),
M(t1_max, t2_max, t3_min),
M(t1_max, t2_max, t3_max),
]
signatures = [
"#9000=",
"#9001=",
"#9010=",
"#9011=",
"#9100=",
"#9101=",
"#9110=",
"#9111=",
]
script = ""
i = 20000
for (M, S) in zip(vertices, signatures)
script *= S
script *= "VERTEX_POINT('', #$(i));\n"
script *= "#$(i)=CARTESIAN_POINT('', $(parenthesize(M)));\n"
i = i + 1
end
curves = [
BasicBSpline.clamp(M(t1_min, t2_min, :))
BasicBSpline.clamp(M(t1_min, :, t3_min))
BasicBSpline.clamp(M(:, t2_min, t3_min))
BasicBSpline.clamp(M(t1_min, :, t3_max))
BasicBSpline.clamp(M(:, t2_min, t3_max))
BasicBSpline.clamp(M(t1_min, t2_max, :))
BasicBSpline.clamp(M(:, t2_max, t3_min))
BasicBSpline.clamp(M(t1_max, t2_min, :))
BasicBSpline.clamp(M(t1_max, :, t3_min))
BasicBSpline.clamp(M(:, t2_max, t3_max))
BasicBSpline.clamp(M(t1_max, :, t3_max))
BasicBSpline.clamp(M(t1_max, t2_max, :))
]
signatures = [
"#4002="
"#4020="
"#4200="
"#4021="
"#4201="
"#4012="
"#4210="
"#4102="
"#4120="
"#4211="
"#4121="
"#4112="
]
for (M, S) in zip(curves, signatures)
p = degree(bsplinespaces(M)[1])
k = knotvector(bsplinespaces(M)[1])
v = BasicBSpline._vec(unique(k))
d = countknots.(Ref(k), v)
w = weights(M)
script *= S
n1 = dim(bsplinespaces(M)[1])
script *= "(BOUNDED_CURVE() B_SPLINE_CURVE($p, $(parenthesize("#".*string.(i.+(1:n1)))), .UNSPECIFIED., .F., .F.) B_SPLINE_CURVE_WITH_KNOTS($(parenthesize(d)), $(parenthesize(v)), .UNSPECIFIED.) CURVE() GEOMETRIC_REPRESENTATION_ITEM() RATIONAL_B_SPLINE_CURVE($(parenthesize(w))) REPRESENTATION_ITEM(''));\n"
script *= join(["#$(i+j)=CARTESIAN_POINT('', $(parenthesize(vec(controlpoints(M))[j])));" for j in 1:n1], "\n")
script *= "\n"
i = i + n1
end
surfaces = [
BasicBSpline.expand_domain(BasicBSpline.clamp(M(t1_min, :, :)), 0.1),
BasicBSpline.expand_domain(BasicBSpline.clamp(M(:, t2_min, :)), 0.1),
BasicBSpline.expand_domain(BasicBSpline.clamp(M(:, :, t3_min)), 0.1),
BasicBSpline.expand_domain(BasicBSpline.clamp(M(t1_max, :, :)), 0.1),
BasicBSpline.expand_domain(BasicBSpline.clamp(M(:, t2_max, :)), 0.1),
BasicBSpline.expand_domain(BasicBSpline.clamp(M(:, :, t3_max)), 0.1),
]
signatures = [
"#5088=",
"#5808=",
"#5880=",
"#5188=",
"#5818=",
"#5881=",
]
for (M, S) in zip(surfaces, signatures)
p = degree.(bsplinespaces(M))
n1, n2 = dim.(bsplinespaces(M))
k1, k2 = knotvector.(bsplinespaces(M))
v1, v2 = BasicBSpline._vec(unique(k1)), BasicBSpline._vec(unique(k2))
d1, d2 = countknots.(Ref(k1), v1), countknots.(Ref(k2), v2)
w = weights(M)
script *= S
script *= "(BOUNDED_SURFACE() B_SPLINE_SURFACE($(p[1]), $(p[2]), $(parenthesize("#".*string.(i.+reshape(1:n1*n2,n1,n2)))), .UNSPECIFIED., .F., .F., .F.) B_SPLINE_SURFACE_WITH_KNOTS($(parenthesize(d1)), $(parenthesize(d2)), $(parenthesize(v1)), $(parenthesize(v2)), .PIECEWISE_BEZIER_KNOTS.) GEOMETRIC_REPRESENTATION_ITEM() RATIONAL_B_SPLINE_SURFACE($(parenthesize(w))) REPRESENTATION_ITEM('') SURFACE());\n"
script *= join(["#$(i+j)=CARTESIAN_POINT('', $(parenthesize(vec(controlpoints(M))[j])));" for j in 1:(n1*n2)], "\n")
script *= "\n"
i = i + n1*n2
end
script = """
ISO-10303-21;
HEADER;
FILE_DESCRIPTION( ('STEP AP242', 'CAx-IF Rec.Pracs.---Representation and Presentation of Product Manufacturing Information (PMI) ---4.0---2014-10-13', 'CAx-IF Rec.Pracs.---3D Tessellated Geometry--0.4---2014-09-14', '2;1') , '2;1');
FILE_NAME( 'uuid', 'datetime', ('') , ('') , '', 'BasicBSpline.jl', ' ');
FILE_SCHEMA (('AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF { 1 0 10303 442 1 1 4 }'));
ENDSEC;
DATA;
#10=SHAPE_REPRESENTATION_RELATIONSHIP('', '', #111, #11);
#11=ADVANCED_BREP_SHAPE_REPRESENTATION('', (#109) , #193);
#2002=ORIENTED_EDGE('', *, *, #3002, .T.);
#2020=ORIENTED_EDGE('', *, *, #3020, .T.);
#2200=ORIENTED_EDGE('', *, *, #3200, .T.);
#2021=ORIENTED_EDGE('', *, *, #3021, .T.);
#2201=ORIENTED_EDGE('', *, *, #3201, .T.);
#2012=ORIENTED_EDGE('', *, *, #3012, .T.);
#2210=ORIENTED_EDGE('', *, *, #3210, .T.);
#2102=ORIENTED_EDGE('', *, *, #3102, .T.);
#2120=ORIENTED_EDGE('', *, *, #3120, .T.);
#2211=ORIENTED_EDGE('', *, *, #3211, .T.);
#2121=ORIENTED_EDGE('', *, *, #3121, .T.);
#2112=ORIENTED_EDGE('', *, *, #3112, .T.);
#2003=ORIENTED_EDGE('', *, *, #3002, .F.);
#2030=ORIENTED_EDGE('', *, *, #3020, .F.);
#2300=ORIENTED_EDGE('', *, *, #3200, .F.);
#2031=ORIENTED_EDGE('', *, *, #3021, .F.);
#2301=ORIENTED_EDGE('', *, *, #3201, .F.);
#2013=ORIENTED_EDGE('', *, *, #3012, .F.);
#2310=ORIENTED_EDGE('', *, *, #3210, .F.);
#2103=ORIENTED_EDGE('', *, *, #3102, .F.);
#2130=ORIENTED_EDGE('', *, *, #3120, .F.);
#2311=ORIENTED_EDGE('', *, *, #3211, .F.);
#2131=ORIENTED_EDGE('', *, *, #3121, .F.);
#2113=ORIENTED_EDGE('', *, *, #3112, .F.);
#3002=EDGE_CURVE('', #9000, #9001, #4002, .T.);
#3020=EDGE_CURVE('', #9000, #9010, #4020, .T.);
#3200=EDGE_CURVE('', #9000, #9100, #4200, .T.);
#3021=EDGE_CURVE('', #9001, #9011, #4021, .T.);
#3201=EDGE_CURVE('', #9001, #9101, #4201, .T.);
#3012=EDGE_CURVE('', #9010, #9011, #4012, .T.);
#3210=EDGE_CURVE('', #9010, #9110, #4210, .T.);
#3102=EDGE_CURVE('', #9100, #9101, #4102, .T.);
#3120=EDGE_CURVE('', #9100, #9110, #4120, .T.);
#3211=EDGE_CURVE('', #9011, #9111, #4211, .T.);
#3121=EDGE_CURVE('', #9101, #9111, #4121, .T.);
#3112=EDGE_CURVE('', #9110, #9111, #4112, .T.);
#7088=EDGE_LOOP('', (#2002, #2021, #2013, #2030));
#7808=EDGE_LOOP('', (#2200, #2102, #2301, #2003));
#7880=EDGE_LOOP('', (#2020, #2210, #2130, #2300));
#7188=EDGE_LOOP('', (#2131, #2103, #2120, #2112));
#7818=EDGE_LOOP('', (#2113, #2310, #2012, #2211));
#7881=EDGE_LOOP('', (#2311, #2031, #2201, #2121));
#1088=FACE_BOUND('', #7088, .T.);
#1808=FACE_BOUND('', #7808, .T.);
#1880=FACE_BOUND('', #7880, .T.);
#1188=FACE_BOUND('', #7188, .T.);
#1818=FACE_BOUND('', #7818, .T.);
#1881=FACE_BOUND('', #7881, .T.);
#94=ADVANCED_FACE('', (#1088) , #5088, .T.);
#96=ADVANCED_FACE('', (#1808) , #5808, .T.);
#98=ADVANCED_FACE('', (#1880) , #5880, .F.);
#99=ADVANCED_FACE('', (#1188) , #5188, .T.);
#97=ADVANCED_FACE('', (#1818) , #5818, .T.);
#95=ADVANCED_FACE('', (#1881) , #5881, .T.);
#100=CLOSED_SHELL('', (#94, #95, #96, #97, #98, #99));
#101=STYLED_ITEM('', (#102) , #109);
#102=PRESENTATION_STYLE_ASSIGNMENT((#103));
#103=SURFACE_STYLE_USAGE(.BOTH., #104);
#104=SURFACE_SIDE_STYLE('', (#105));
#105=SURFACE_STYLE_FILL_AREA(#106);
#106=FILL_AREA_STYLE('', (#107));
#107=FILL_AREA_STYLE_COLOUR('', #108);
#108=COLOUR_RGB('', 0.584, 0.345, 0.698);
#109=MANIFOLD_SOLID_BREP('Part name', #100);
#110=SHAPE_DEFINITION_REPRESENTATION(#198, #111);
#111=SHAPE_REPRESENTATION('Part name', (#112) , #193);
#112=AXIS2_PLACEMENT_3D('', #8222, #115, #116);
#115=DIRECTION('', (0., 0., 1.));
#116=DIRECTION('', (1., 0., 0.));
#8222=CARTESIAN_POINT('', (0., 0., 0.));
$script
#192=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('', (#101) , #193);
#193=(GEOMETRIC_REPRESENTATION_CONTEXT(3) GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#194)) GLOBAL_UNIT_ASSIGNED_CONTEXT((#197, #196, #195)) REPRESENTATION_CONTEXT('Part name', 'TOP_LEVEL_ASSEMBLY_PART'));
#194=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.01912537205686E-5) , #197, 'DISTANCE_ACCURACY_VALUE', 'Maximum Tolerance applied to model');
#195=(NAMED_UNIT(*) SI_UNIT(\$, .STERADIAN.) SOLID_ANGLE_UNIT());
#196=(NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT(\$, .RADIAN.));
#197=(LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(\$, .METRE.));
#198=PRODUCT_DEFINITION_SHAPE('', '', #199);
#199=PRODUCT_DEFINITION('', '', #201, #200);
#200=PRODUCT_DEFINITION_CONTEXT('', #207, 'design');
#201=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('', '', #203, .NOT_KNOWN.);
#202=PRODUCT_RELATED_PRODUCT_CATEGORY('', '', (#203));
#203=PRODUCT('Part name', 'Part name', 'Part name', (#205));
#204=PRODUCT_CATEGORY('', '');
#205=PRODUCT_CONTEXT('', #207, 'mechanical');
#206=APPLICATION_PROTOCOL_DEFINITION('international standard', 'ap242_managed_model_based_3d_engineering', 2011, #207);
#207=APPLICATION_CONTEXT('managed model based 3d engineering');
ENDSEC;
END-ISO-10303-21;
"""
return script
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment