3Dモデルの寸法検証が嘘をつく7つの場面|レイキャストとメッシュ検査の落とし穴
3Dモデルの寸法をスクリプトで検証していると、あるとき気づきます。検証コードのほうが間違っていた。
厄介なのは、間違った検証が「不合格」ではなく「合格」を返す場合です。不合格なら調べ直します。合格ならそのまま印刷して、現物で初めて気づきます。
この記事は、レイキャストとメッシュ検査で実際に嘘をつかれた場面と、その回避法の記録です。
1. プローブが構造の穴を通っている
「この座標に実体があるか」をレイキャストで判定する。素直に部品の軸上を狙う。ここが最初の罠です。
スナップフィットのペグには軸方向にスリットが入っています。支柱の中心には通し穴が開いています。つまり軸上を撃つと、正常な部品でも必ず「実体なし」が返ります。
これで「部品が欠けている」と誤判定し、実際には正しかったモデルを直そうとしました。
対処は、軸上・端面の平面上・割りの中心を避け、0.9mm程度ずらした点で判定すること。構造的に穴が開いている場所を狙わないという、当たり前だが忘れやすい原則です。
そもそもレイキャストによる内外判定は、軸上や面上を通る点では数学的に不定になります。境界をかすめるレイは、実装によって「当たった」とも「当たらない」とも解釈されます。避けるのが正解です。
2. 円筒のファセット境界を撃っている
これは発見に時間がかかりました。
円筒を水平方向から多角度でレイキャストして寸法を測る。0°、45°、90°、135°……と等間隔で撃つ。特定の角度だけ、無限ループやゼロヒット、あるいは明らかに誤った距離が返ります。
原因は、3Dの円筒が本当は多角形だからです。24角形なら15°ごとに頂点があり、0°や45°といったキリのよい角度は、ちょうど頂点やエッジの真上を通ることがあります。境界を撃つと判定が不定になります。
対処は単純です。キリのよい角度を避け、11.25°のようなオフセットした角度を使う。
この問題は実害が出ました。検査側が「機能していない、FAIL」と判定し、モデリング側が「それは別の部分を測っている」と反論する対立が起きました。最終的に検査側が測定角度を変えて再検証し、判定を撤回しました。どちらも誠実に作業していて、測り方だけが違っていたという状況です。
3. サンプリングの刻みが急変部を飛び越える
螺旋状のスロープの頭上クリアランスを、2mm刻みで補間しながら全域測定しました。結果は合格。
実際には見落とした区間がありました。
螺旋の内縁が急に折り返す部分で、座標が一気に変化していました。2mm刻みではその区間をまたいでしまい、最も狭い場所を測っていなかったのです。1mm刻みで測り直すと、必要値を下回る箇所が見つかりました。
サンプリング間隔は、形状が最も急に変わる場所を基準に決める必要があります。 「全域を測った」は「全域を漏れなく測った」を意味しません。
4. 座標系の符号が逆
これが最も怖い種類の間違いです。
2つの部品を組み合わせたときのクリアランスを測るため、片方に座標オフセットをかけて重ねる。このオフセットの符号を間違えていました。Z+120とすべきところをZ−120にしていたのです。
結果、測定していたのは実際には起こりえない位置関係でした。数値はきれいに出ます。合格も出ます。しかし測っている対象が現実と違う。
この符号ミスが発覚したとき、それ以前に「合格」としていた測定結果すべての信頼性が疑わしくなりました。測定系そのものの誤りは、個々の測定値をいくら精密にしても検出できません。
対処は、測定を始める前に「明らかに正しいはずの値」で検算すること。既知の寸法を1つ測って、期待値と一致するか確かめてから本測定に入ります。
5. 非多様体ゼロでも壊れている
Blenderのbmeshで非多様体を判定して0。合格。ところが出力したSTLには縮退ポリゴンが残っていました。
面積がほぼゼロの四角形で、頂点が2組完全に一致しているものです。bmeshのエッジ判定はこれをすり抜けます。
確実に検出するには、STLを三角形単位で直接パースし、エッジの共有数を数えます。エッジを frozenset((v0, v1)) でカウントし、2以外を検出する。閉じた多様体なら、すべてのエッジはちょうど2つの三角形に共有されるためです。
ツールの合格判定を信じるのではなく、成果物そのものを別系統の方法で検査する。これが原則です。
6. 幾何の検算を省かない
角にR3.0の丸みが付いているかを、対角方向にプローブして確認しました。
「角から+0.3mmと+0.7mmは外側(実体なし)、+1.5mmと+2.5mmも外側のはず」と考えました。間違いです。
半径Rの丸めを対角方向に見たとき、実体に戻る距離は R×(√2−1)。R3.0なら約1.24mmです。つまり+1.5mmはすでに実体の中。
正しい期待値は「+0.3/+0.7=外側、+1.5/+2.5=実体」でした。検算せずに直感で期待値を置いたため、正しいモデルを不合格と判定しかけました。
プローブの期待値は、直感ではなく計算で出す。
7. 「総数が変化なし」は根拠にならない
最後に、比較の落とし穴です。
モデルに装飾を追加したあと、非多様体エッジの数を確認しました。追加前20、追加後20。「変化なし=今回の作業は無関係」と結論しました。
実際は違いました。エッジ単位で前後を比較すると、無関係なジャンク三角形が3枚たまたま消滅し、別の異常が新たに発生して、内訳が入れ替わったまま総数だけ20に保たれていたのです。
結論の方向性は間違っていませんでしたが、「無変化」という判断の根拠は成立していませんでした。
総数の一致は、中身が同じであることを意味しません。 可能な限り座標単位・エッジ単位で差分を取ります。
結局、いちばん効いた対策
ここまで7つ挙げましたが、最も効果があったのは技術的な工夫ではありませんでした。
作る人と検証する人を分けたことです。
自分で作って自分で検証すると、「軸上にスリットがあるのに軸をプローブする」といった思い込みが、そのまま検証手順に持ち込まれます。作ったときの前提が、検証の前提としてコピーされてしまう。
検証を独立させると、この相関が切れます。実際、独立検証によって「直したつもり」の見落としが複数回見つかりました。逆に検証側の誤りをモデリング側が指摘して覆したこともあります。どちらが正しいかは、そのつど具体的な座標と数値を出して決着させます。
検証を頼むときは、こう要求すると精度が上がります。
- 「OKです」ではなく実測値を報告させる
- 既知の罠(軸上プローブ禁止など)を最初に共有する
- 保護すべき形状と座標を明示する
検証環境
- Blender 5.1(bmesh/レイキャスト)
- 用途:FDM 3Dプリント用の実体モデル検証
本記事の内容は個人が実作業で遭遇した事例に基づくものであり、動作を保証するものではありません。記事中の製品名・会社名は各社の商標または登録商標です。