# 欧霓博 SC 系列示例数据生成器:STEP 变体文件 + params.csv # 用法: powershell -NoProfile -ExecutionPolicy Bypass -File tools\gen-step.ps1 # 说明: 以极简封闭 B-rep 圆柱(MANIFOLD_SOLID_BREP)组合出简化气缸模型 # (后盖 + 缸体 + 前盖 + 活塞杆 4 个实体), 尺寸随缸径/行程参数变化。 param( [string]$OutDir = (Join-Path $PSScriptRoot '..\onb-sc') ) $inv = [System.Globalization.CultureInfo]::InvariantCulture $stepDir = Join-Path $OutDir 'step' $csvPath = Join-Path $OutDir 'params.csv' New-Item -ItemType Directory -Force -Path $stepDir | Out-Null function Format-Num([double]$v) { return $v.ToString('0.###', $inv) } # 单个圆柱实体的实体行 (OCCT 兼容拓扑: 顶点在圆周上+全圆闭边+接缝边, 共 36 个实体) # 约定: 圆心点 = (x, 0, z) 是仅有的 y=0 点 (供解析器识别); 顶点 = (x, r, z) 在 +Y 方向 function New-CylinderEntities([int]$id, [double]$x, [double]$y, [double]$z, [double]$r, [double]$len) { $X = Format-Num $x $Y = Format-Num $y $Z = Format-Num $z $ZT = Format-Num ($z + $len) $R = Format-Num $r $VY = Format-Num ($y + $r) # 顶点在圆周 +Y 处 (y=0 留给圆心供解析) $e = @( "#$($id)=DIRECTION('',(0.,0.,1.));", # 轴 "#$($id+1)=CARTESIAN_POINT('',($X,$Y,$Z));", # 底圆心 "#$($id+2)=CARTESIAN_POINT('',($X,$Y,$ZT));", # 顶圆心 "#$($id+3)=DIRECTION('',(1.,0.,0.));", # 参考方向 "#$($id+4)=AXIS2_PLACEMENT_3D('',#$($id+1),#$($id),#$($id+3));", # 底放置 "#$($id+5)=CARTESIAN_POINT('',($X,$VY,$Z));", # 底顶点(圆周上) "#$($id+6)=CARTESIAN_POINT('',($X,$VY,$ZT));", # 顶顶点(圆周上) "#$($id+7)=VERTEX_POINT('',#$($id+5));", "#$($id+8)=VERTEX_POINT('',#$($id+6));", "#$($id+9)=CIRCLE('',#$($id+4),$R);", # 底圆 "#$($id+10)=EDGE_CURVE('',#$($id+7),#$($id+7),#$($id+9),.T.);", # 底圆闭边 "#$($id+11)=CYLINDRICAL_SURFACE('',#$($id+4),$R);", "#$($id+12)=PLANE('',#$($id+4));", # 底面 "#$($id+13)=DIRECTION('',(0.,0.,1.));", "#$($id+14)=AXIS2_PLACEMENT_3D('',#$($id+2),#$($id+13),#$($id+3));", # 顶放置 "#$($id+15)=PLANE('',#$($id+14));", # 顶面 "#$($id+16)=CIRCLE('',#$($id+14),$R);", # 顶圆 "#$($id+17)=EDGE_CURVE('',#$($id+8),#$($id+8),#$($id+16),.T.);", # 顶圆闭边 "#$($id+18)=DIRECTION('',(0.,0.,1.));", "#$($id+19)=VECTOR('',#$($id+18),1.);", "#$($id+20)=LINE('',#$($id+5),#$($id+19));", # 接缝线 "#$($id+21)=EDGE_CURVE('',#$($id+7),#$($id+8),#$($id+20),.T.);", # 接缝边 "#$($id+22)=ORIENTED_EDGE('',*,*,#$($id+10),.T.);", # 底环 "#$($id+23)=ORIENTED_EDGE('',*,*,#$($id+17),.T.);", # 顶环 "#$($id+24)=ORIENTED_EDGE('',*,*,#$($id+21),.T.);", # 壁环: 缝上 "#$($id+25)=ORIENTED_EDGE('',*,*,#$($id+17),.T.);", "#$($id+26)=ORIENTED_EDGE('',*,*,#$($id+21),.F.);", # 缝下 "#$($id+27)=ORIENTED_EDGE('',*,*,#$($id+10),.F.);", "#$($id+28)=EDGE_LOOP('',(#$($id+22)));", "#$($id+29)=EDGE_LOOP('',(#$($id+23)));", "#$($id+30)=EDGE_LOOP('',(#$($id+24),#$($id+25),#$($id+26),#$($id+27)));", "#$($id+31)=ADVANCED_FACE('',(#$($id+30)),#$($id+11),.T.);", # 柱壁 "#$($id+32)=ADVANCED_FACE('',(#$($id+28)),#$($id+12),.F.);", # 底面(法线朝下) "#$($id+33)=ADVANCED_FACE('',(#$($id+29)),#$($id+15),.T.);", # 顶面(法线朝上) "#$($id+34)=CLOSED_SHELL('',(#$($id+31),#$($id+32),#$($id+33)));", "#$($id+35)=MANIFOLD_SOLID_BREP('',#$($id+34));" ) return $e } # 尾部共享实体: 每个实体注入 STYLED_ITEM 颜色 (occt-import-js 对无颜色模型会崩) # 从 $id 开始: 每实体 7 个颜色实体 + 14 个尾部实体 function New-TailEntities([int]$id, [int[]]$solidIds) { $t = New-Object System.Collections.Generic.List[string] $styled = New-Object System.Collections.Generic.List[string] $c = $id foreach ($s in $solidIds) { $t.Add("#$c=COLOUR_RGB('',0.65,0.72,0.85);") $t.Add("#$($c+1)=FILL_AREA_STYLE_COLOUR('',#$c);") $t.Add("#$($c+2)=SURFACE_STYLE_FILL_AREA(#$($c+1));") $t.Add("#$($c+3)=SURFACE_SIDE_STYLE('',(#$($c+2)));") $t.Add("#$($c+4)=SURFACE_STYLE_USAGE(.BOTH.,#$($c+3));") $t.Add("#$($c+5)=PRESENTATION_STYLE_ASSIGNMENT((#$($c+4)));") $t.Add("#$($c+6)=STYLED_ITEM('',(#$($c+5)),#$s);") $styled.Add("#$($c+6)") $c += 7 } $items = (($solidIds | ForEach-Object { "#$_" }) + $styled) -join ',' $t.Add("#$c=SHAPE_REPRESENTATION('',($items),#$($c+1));") $t.Add("#$($c+1)=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#$($c+2)))GLOBAL_UNIT_ASSIGNED_CONTEXT((#$($c+3),#$($c+4),#$($c+5)))REPRESENTATION_CONTEXT('',''));") $t.Add("#$($c+2)=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-06),#$($c+3),'');") $t.Add("#$($c+3)=(LENGTH_UNIT()NAMED_UNIT(*)SI_UNIT(.MILLI.,.METRE.));") $t.Add("#$($c+4)=(NAMED_UNIT(*)PLANE_ANGLE_UNIT()SI_UNIT($,.RADIAN.));") $t.Add("#$($c+5)=(NAMED_UNIT(*)SI_UNIT($,.STERADIAN.)SOLID_ANGLE_UNIT());") $t.Add("#$($c+6)=PRODUCT('OUNIBO_SC','OUNIBO_SC','',(#$($c+7)));") $t.Add("#$($c+7)=PRODUCT_CONTEXT('',#$($c+8),'mechanical');") $t.Add("#$($c+8)=APPLICATION_CONTEXT('configuration controlled 3d designs of mechanical parts and assemblies');") $t.Add("#$($c+9)=PRODUCT_DEFINITION_FORMATION('','',#$($c+6));") $t.Add("#$($c+10)=PRODUCT_DEFINITION('design','',#$($c+9),#$($c+11));") $t.Add("#$($c+11)=PRODUCT_DEFINITION_CONTEXT('part definition',#$($c+8),'design');") $t.Add("#$($c+12)=PRODUCT_DEFINITION_SHAPE('','',#$($c+10));") $t.Add("#$($c+13)=SHAPE_DEFINITION_REPRESENTATION(#$($c+12),#$c);") return $t } # ---- 型号与规则定义 (见 coding-rules.md) ---- # 缸径 16: 行程仅 25/50, 无磁石; 磁石 S 要求缸径>=25; 中摆 CB 要求行程<=75 $bores = @(16, 25, 32, 40) $strokesAll = @(25, 50, 75, 100) $mountsAll = @('FA', 'LB', 'CB') $encNoBom = New-Object System.Text.UTF8Encoding($false) $encBom = New-Object System.Text.UTF8Encoding($true) $csvLines = New-Object System.Collections.Generic.List[string] $csvLines.Add('model_code,bore,stroke,magnet,mount,step_file') $count = 0 foreach ($bore in $bores) { $strokes = if ($bore -eq 16) { @(25, 50) } else { $strokesAll } $magnets = if ($bore -eq 16) { @('') } else { @('', 'S') } foreach ($stroke in $strokes) { $mounts = if ($stroke -gt 75) { @('FA', 'LB') } else { $mountsAll } foreach ($magnet in $magnets) { foreach ($mount in $mounts) { $model = "SC$bore`x$stroke$magnet-$mount" $stepFile = "$model.step" # ---- 简化气缸尺寸 (mm): 后盖 + 缸体 + 前盖 + 活塞杆, 沿 Z 轴 ---- $bodyR = $bore / 2.0 + 2.0 # 缸体外径 $bodyLen = $stroke + 60.0 # 缸体长度(随行程) $capR = $bore / 2.0 + 5.0 # 端盖外径 $capLen = 8.0 # 后盖厚度 $fcapLen = 10.0 # 前盖厚度 $rodR = [Math]::Max($bore / 5.0, 3.0) $rodBot = $bodyLen - 14.0 # 活塞杆埋入缸体 $rodLen = $stroke + 34.0 $lines = New-Object System.Collections.Generic.List[string] $lines.Add('ISO-10303-21;') $lines.Add('HEADER;') $lines.Add("FILE_DESCRIPTION(('OUNIBO SC series sample part $model'),'2;1');") $lines.Add("FILE_NAME('$stepFile','2026-06-02T00:00:00',('OUNIBO'),('OUNIBO'),'','','');") $lines.Add("FILE_SCHEMA(('CONFIG_CONTROL_DESIGN'));") $lines.Add('ENDSEC;') $lines.Add('DATA;') $ids = New-Object System.Collections.Generic.List[int] $nextId = 1 $cyls = New-Object System.Collections.Generic.List[object] $cyls.Add(@{ z = -$capLen; r = $capR; len = $capLen }) # 后盖 $cyls.Add(@{ z = 0.0; r = $bodyR; len = $bodyLen }) # 缸体 $cyls.Add(@{ z = $bodyLen; r = $capR; len = $fcapLen }) # 前盖 $cyls.Add(@{ z = $rodBot; r = $rodR; len = $rodLen }) # 活塞杆 foreach ($cyl in $cyls) { [string[]]$entities = New-CylinderEntities -id $nextId -x 0 -y 0 -z $cyl['z'] -r $cyl['r'] -len $cyl['len'] $lines.AddRange($entities) $ids.Add($nextId + 35) # MANIFOLD_SOLID_BREP 实体号 $nextId += 36 } [string[]]$tail = New-TailEntities -id $nextId -solidIds $ids.ToArray() $lines.AddRange($tail) $lines.Add('ENDSEC;') $lines.Add('END-ISO-10303-21;') [System.IO.File]::WriteAllLines((Join-Path $stepDir $stepFile), $lines.ToArray(), $encNoBom) $csvLines.Add("$model,$bore,$stroke,$magnet,$mount,$stepFile") $count++ } } } } # ---- MAQ 迷你气缸系列 (多系列演示): 缸径 6/10/16, 行程 10/20/30/40 ---- # 规则: 缸径 6 仅行程 10/20 且无磁石; 安装仅 FA/LB $csvLinesM = New-Object System.Collections.Generic.List[string] $csvLinesM.Add('model_code,bore,stroke,magnet,mount,step_file') $countM = 0 foreach ($bore in @(6, 10, 16)) { $strokes = if ($bore -eq 6) { @(10, 20) } else { @(10, 20, 30, 40) } $magnets = if ($bore -eq 6) { @('') } else { @('', 'S') } foreach ($stroke in $strokes) { foreach ($magnet in $magnets) { foreach ($mount in @('FA', 'LB')) { $model = "MAQ$bore`x$stroke$magnet-$mount" $stepFile = "$model.step" $bodyR = $bore / 2.0 + 1.5 $bodyLen = $stroke + 40.0 $capR = $bore / 2.0 + 4.0 $capLen = 6.0 $fcapLen = 8.0 $rodR = [Math]::Max($bore / 5.0, 2.0) $rodBot = $bodyLen - 10.0 $rodLen = $stroke + 24.0 $lines = New-Object System.Collections.Generic.List[string] $lines.Add('ISO-10303-21;') $lines.Add('HEADER;') $lines.Add("FILE_DESCRIPTION(('OUNIBO MAQ series sample part $model'),'2;1');") $lines.Add("FILE_NAME('$stepFile','2026-06-02T00:00:00',('OUNIBO'),('OUNIBO'),'','','');") $lines.Add("FILE_SCHEMA(('CONFIG_CONTROL_DESIGN'));") $lines.Add('ENDSEC;') $lines.Add('DATA;') $ids = New-Object System.Collections.Generic.List[int] $nextId = 1 $cyls = New-Object System.Collections.Generic.List[object] $cyls.Add(@{ z = -$capLen; r = $capR; len = $capLen }) $cyls.Add(@{ z = 0.0; r = $bodyR; len = $bodyLen }) $cyls.Add(@{ z = $bodyLen; r = $capR; len = $fcapLen }) $cyls.Add(@{ z = $rodBot; r = $rodR; len = $rodLen }) foreach ($cyl in $cyls) { [string[]]$entities = New-CylinderEntities -id $nextId -x 0 -y 0 -z $cyl['z'] -r $cyl['r'] -len $cyl['len'] $lines.AddRange($entities) $ids.Add($nextId + 35) $nextId += 36 } [string[]]$tail = New-TailEntities -id $nextId -solidIds $ids.ToArray() $lines.AddRange($tail) $lines.Add('ENDSEC;') $lines.Add('END-ISO-10303-21;') [System.IO.File]::WriteAllLines((Join-Path $stepDir $stepFile), $lines.ToArray(), $encNoBom) $csvLinesM.Add("$model,$bore,$stroke,$magnet,$mount,$stepFile") $countM++ } } } } [System.IO.File]::WriteAllLines($csvPath, $csvLines.ToArray(), $encBom) [System.IO.File]::WriteAllLines((Join-Path $OutDir 'params_maq.csv'), $csvLinesM.ToArray(), $encBom) Write-Output "生成完成: SC $count 个 + MAQ $countM 个 STEP 文件 -> $stepDir" Write-Output "参数表: $csvPath / params_maq.csv"