Last active
March 29, 2025 15:54
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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