簡體   English   中英

點的查詢在網格內 Maya python api

[英]Querying of a point is within a mesh maya python api

我試圖找出一種計算世界空間點是否在任意網格內的方法。

如果它不是立方體或球體,我不太確定如何計算它的數學方法。

任何幫助都會很棒!

人們可以使用一種簡單的光線追蹤技巧來測試您是在形狀的內部還是外部。 事實證明,2D、3D 對象或什至可能更高維的對象具有整潔的屬性。 也就是說,如果您在任何方向上發射任意光線,當且僅當您擊中形狀的邊界且次數為奇數時,您才處於形狀內部。 無需知道正常方向或任何東西。 只要知道你有多少個交叉點。 這很容易在 2D 中進行可視化,並且由於 3D 只是許多 2D 切片,因此同樣適用於 3D。

在此處輸入圖片說明

圖 1:從任意方向的一個點射出一條射線,如果在里面,即使在外面,也會產生奇數次命中,所以 O 1在里面,O 2不在。 作為一種特殊情況,需要針對曲線測試斜視命中,因為它們使 2 個命中重合在一個位置 (O 3 )。

在此處輸入圖片說明

圖 2:網格曲面具有更好的邊界條件,因為只有頂點命中是掠過然而,大多數跟蹤引擎忽略掠過,因為完全垂直的命中 (O 4 ) 會出現問題,因此它們的行為適合此測試的目的。 瑪雅示蹤劑也不例外。

請注意,此方法不需要關閉曲面,它仍然有效,它只是關閉了光線方向上的間隙,而打開的曲面可能會報告奇怪的結果。 但在某些情況下是可以接受的。

誠然,光線追蹤在沒有加速例程的情況下是非常繁重的操作,但是一旦加速到位,它就會變得非常快。 Maya API 為此提供了一種方法。 請注意,首先構建加速器,然后每次后續調用都便宜得多。 這是一個快速編寫的沒有加速的腳手架,請參閱MFnMesh 的文檔以獲取有關如何加速的更多信息:

import maya.cmds as cmd
import maya.OpenMaya as om 

def test_if_inside_mesh(point=(0.0, 0.0, 0.0), dir=(0.0, 0.0, 1.0)):
    sel = om.MSelectionList()
    dag = om.MDagPath()

    #replace torus with arbitrary shape name
    sel.add("pTorusShape1")
    sel.getDagPath(0,dag)

    mesh = om.MFnMesh(dag)

    point = om.MFloatPoint(*point)
    dir = om.MFloatVector(*dir)
    farray = om.MFloatPointArray()

    mesh.allIntersections(
            point, dir,
            None, None,
            False, om.MSpace.kWorld,
            10000, False,
            None, # replace none with a mesh look up accelerator if needed
            False,
            farray,
            None, None,
            None, None,
            None
        ) 
    return farray.length()%2 == 1   

#test
cmd.polyTorus()
print test_if_inside_mesh()
print test_if_inside_mesh((1,0,0))

在您的具體情況下,這可能是矯枉過正。 我假設你在做某種拒絕抽樣。 也可以用棱鏡構建物體並使用類似重心的坐標隨機化。 這具有從不浪費結果的優點。 但是跟蹤代碼通常更容易使用。

如果您嘗試為任何網格解決此問題,您將遇到麻煩,因為並非每個任意網格都是關閉的。 如果可以假設您的網格是閉合且結構良好的,那么您可能需要執行類似 3D 洪水填充算法的操作,以確定是否有一條路徑可以從您正在測試的點看到對象外部的點。

如果您願意采用更寬松的方法來給出近似答案,並假設法線都統一向外指向,則此頁面上有一個用 MEL 編寫的代碼示例,您可以將其轉換為 Python。

http://forums.cgsociety.org/archive/index.php/t-747732.html

馬克是正確的,沒有保證測試適用於開放網格。 此外,任意網格測試將緩慢且昂貴,因此請先嘗試廉價測試(邊界球體和/或邊界框)。 如果您的網格上有任何開放的邊緣,您也可以告訴用戶“對不起,沒有骰子”——這保證了“內部”的概念沒有解決方案

如果您想要一個比邊界測試更好但又不像體素測試那么昂貴的近似答案,您可以使用qHull或類似的東西為您的網格生成凸包並針對凸網格進行測試。 這不會處理由內向外扭曲的網格的嚴重凹陷,但會比邊界測試更優雅地捕捉形狀奇特的物體。

如果您確實需要速度或擁有復雜的對象,您可能希望對對象進行體素化並測試體素數據。 這對於腳本編寫來說通常過於數學化(例如,請參閱)並且實現起來並非易事。

綜上所述,這里有一個使用內置 nParticle 的體素近似值:

如果您有 nParticles(maya 2011 +),您可以嘗試用粒子填充您的對象( nParticles > createNParticles > Fill Object )。 然后,您可以根據粒子集中每個粒子的位置對您的點進行距離測試。 如果到任何粒子的距離小於或等於粒子的半徑,則您處於 1/2 粒子半徑精度內的“內部”。 您會注意到某些形狀不能由 nparticles 填充 - 這些形狀無論如何都無法測試“內部性”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM