押し出しを元に戻す方法

Aug 21 2020

オブジェクトに対して実行した押し出しを回復するための最良の方法は何ですか?

上記は単なる例ですが、ケースを説明する必要があります。そして、私は次のような答えを探していません:新しい球を描きます。また、「元に戻す(Ctrl+ Z)」はオプションではありません(設計エラーが遅すぎることに気づきました)。

これまでのところ、2つのオプションを見つけました。

  1. それらの顔をすべて選択して削除します。しかし、それから私は自分の球に穴を開けます。FまたはAlt+Fでキャップを埋めることができますが、表面はもう同じではありません。

  2. 頭に浮かぶ他のオプションは、これをサーフェスに十分に近づけてから、マージ頂点を使用することです。しかし、6つの面の中央にある2つの頂点はどこにもメルトダウンせず、表面も正しく見えません。

回答

4 batFINGER Aug 22 2020 at 00:37

スクリプトバージョン。

面の法線に沿って押し出しを解除します

  • 選択したすべての面の平均法線を検索します。
  • 押し出されたエッジの平均エッジ長を求めます。
  • すべての頂点を元に戻します
  • ダブルスを削除します。(折りたたまれたエッジから)

編集モードで顔を選択し、スクリプトを実行します。

import bpy
import bmesh
from mathutils import Vector

ob = bpy.context.object
me = ob.data

bm = bmesh.from_edit_mesh(me)
faces = [f for f in bm.faces if f.select]
verts = set(v for f in faces for v in f.verts ) # or from selected verts
edges = [e for v in verts for e in v.link_edges
            if not e.select ]
norm = (sum((f.normal for f in faces), Vector()) / len(faces)).normalized()
norm.negate()
d = sum(e.calc_length() for e in edges) / len(edges)

bmesh.ops.translate(
        bm,
        verts=list(verts),
        vec=d * norm,
        )            
bmesh.ops.remove_doubles(
        bm,
        verts=[v for e in edges for v in e.verts],
        dist=1e-5,
        )   
for f in faces:
    f.select_set(True)                 
bmesh.update_edit_mesh(me)

ノート

改善は、選択内の選択されたすべての顔の島を見つけ、島ごとに「突き出さない」ことです。

これは、面法線に沿った押し出しを「押し出し」します。平均的な面の法線の代わりに、任意の(またはすべての平均の)エッジによって定義されたベクトルの方が適しています。

任意の方向が押し出されない

押し出された後、作成された押し出されたエッジは(AFAIK)すべて押し出しベクトルになります。

import bpy
import bmesh
from mathutils import Vector

ob = bpy.context.object
me = ob.data

bm = bmesh.from_edit_mesh(me)
faces = [f for f in bm.faces if f.select]
verts = set(v for f in faces for v in f.verts ) # or from selected verts
edges = [e for v in verts for e in v.link_edges
            if not e.select ]

v0, v1 = sorted(edges[0].verts[:], key=lambda v:v.select)
bmesh.ops.translate(
        bm,
        verts=list(verts),
        vec=v0.co - v1.co,
        )            

bmesh.ops.remove_doubles(
        bm,
        verts=[v for e in edges for v in e.verts],
        dist=1e-5,
        )  
for f in faces:
    f.select_set(True)          
bmesh.update_edit_mesh(me)

スザンヌのテストを追加しました。ダブルスの削除には、削除されたエッジ頂点に応じて面の選択を解除する効果があります。選択を復元するためにスクリプトが更新されました。

8 RobinBetts Aug 21 2020 at 03:50

これは均一な押し出しであり、スケーリングはありません。そう..

  • Alt-生成された面のリングを選択し、Xそれらを削除します
  • ホバー-L分離されたパッチを選択します
  • スナップを「頂点」、「アクティブ」に設定し、パッチ全体を選択し、便利な頂点をアクティブにした状態でG、パッチを元の位置にスナップして戻します。
  • すべての頂点を選択し、M>距離でマージします。
5 moonboots Aug 21 2020 at 22:08

押し出しを削除し、穴のエッジループを選択し、CtrlF> [グリッド塗りつぶし]を押します。穴が埋められ、トポロジが尊重されます([演算子]ボックスでいくつかのパラメータを微調整できます)。

3 RonJensen Aug 21 2020 at 03:57
  1. 変換方向を「通常」に設定します
  2. 押し出し面パッチを選択します
  3. を押しGてつかみZ、法線方向に拘束します
  4. フェイスパッチを元の位置に戻すために最善を尽くします(スナップは役立つはずですが、私のためにそれを機能させることはできません)
  5. 頂点を距離でマージします。