2014-09-30 1 views
0

안녕 폴리 메쉬를 낮은 폴리 메쉬로 변환하는 도구를 만들고 싶습니다. 어떤 문제에 접근하십시오.C#/WPF에서 3D 모델 읽기, 최적화 (폴리곤 크런치) 및 3D 모델 표시에 대한 최선의 접근 방법

저는 C++ 및 DirectX에 대한 경험이 있지만이 도구를 만드는 데 C#/WPF를 사용하는 것을 선호합니다. 또한 C#에 3D 모델을 열고 표시하고 저장하기위한 다양한 라이브러리가 필요합니다. 보기 및 내 WPF 응용 프로그램에서, 나는 나선 3D 툴킷을 사용하는 방법에 대해 생각하고 3D 모델을 표시하려면 3D 모델

을 저장, 읽기

가장 좋은 방법 : 이것은 내 첫 번째 질문에 저를 제공합니다. 나는 3D 모델

을 최적화하기위한 모든 것을에게

가장 좋은 방법을 정점을 최적화하고 밖으로 작성해야하기 때문에 내가 내 자신의 .OBJ 리더를 작성하는거야 내 3D 모델의 정점 데이터를 읽으려면 최적화를 위해서는 특히 많은 수의 버텍스 및 변경 사항을 처리 할 때 까다로워 질 것입니다. 시작시 간단하게 유지하고 가장자리가 인접한 가장자리와 동일한 경사면에 있는지 감지 한 다음 해당 중복 가장자리를 제거하고 모든 것을 후퇴시킵니다.

나중 단계에서는 터보 스모스 수정자가 Max (역 삽입)에서 수행하는 것과 반대의 작업을 수행하여 모델을 단순화하기 위해 LOD를 생성하려고합니다. 지금 당장 시작하는 방법을 알지 못하지만 온라인으로 살펴보고 조금 실험 해 보겠습니다.

마침내 모델을 저장하고 모든 것이 여전히 작동하는지 확인해야합니다.

답변

0

3D 개체를 보려면 Ab3d.PowerToys 라이브러리를 고려해 볼 수 있습니다.이 라이브러리는 무료는 아니지만 WPF 3D로 작업을 크게 단순화하고 많은 샘플이 함께 제공됩니다.

OBJ 파일은 매우 일반적으로 사용되며 읽고 쓰기가 쉬운 매우 간단한 구조이기 때문에 좋습니다. 그러나 객체 계층 구조, 변형, 애니메이션, 뼈 등을 지원하지 않습니다. 다른 데이터 형식을 사용해야 할 때보 다 이러한 객체가 필요할 경우 필요합니다.

안녕하세요 - 폴리 메쉬 최적화에 대한 경험이 없으므로 여기에 조언을 드릴 수는 없습니다. 여기에서는 같은 재질의 메시를 하나의 메쉬로 결합하는 것을 고려할 수도 있습니다. 그리기 호출 수가 줄어들고 성능이 향상 될 수 있습니다.

내 주된 조언은 코드를 작성하여 WPF 3D에서 성능을 향상시키는 방법에 관한 것입니다. 많은 정점을 검사하고 비교할 필요가 있기 때문에 MeshGeometry3D.Positions 및 MeshGeometry3D.TriangleIndices 컬렉션에서 데이터를 가져 오는 것을 방지해야합니다. 컬렉션에서 단일 값에 액세스하는 것은 매우 느립니다 (.Net 소스를 확인하고 각 줄 뒤에 코드 줄이 있습니다.)

따라서 위치 및 TriangleIndices에 대한 Lists (List, List)와 함께 자신 만의 구조를 갖는 것이 좋습니다. 내 관찰에서 구조체 목록 구조체의 간단한 배열을 사용하여보다 빠릅니다 (하지만 목록을 미리 설정해야합니다 - 크기를 생성자에서 설정해야합니다). 이렇게하면 데이터에 훨씬 빠르게 액세스 할 수 있습니다. 또한 추가 부스트가 필요할 때 포인터로 안전하지 않은 블록을 사용할 수도 있습니다. 또한 다른 데이터를 메쉬 클래스에 추가 할 수 있습니다 - 예를 들어 인접한 모서리를 언급 한 경우.

당신이 당신의 위치와 설정 삼각형 인덱스가 있으면, 다음과 같은 코드를 사용하여 WPF의 MeshGeometry3D 개체를 만들 수 있습니다

var wpfMesh = new MeshGeometry3D() 
{ 
    Positions = new Point3DCollection(optimizedPositions), 
    TriangleIndices = new Int32Collection(optimizedTriangleIndices) 
}; 

이 각를 Point3D 위치에 모음을 추가하는 것보다 더 빠른입니다.

wpfMesh의 인스턴스를 변경하지 않으므로 (변경 될 때마다 새로운 MeshGeometry3D를 생성합니다),이를 고정 할 수 있습니다 (Freeze()). 이를 통해 WPF는 그리기 호출 수를 줄이기 위해 메시를 최적화 (정점 버퍼에 결합) 할 수 있습니다. 더욱이, MeshGeometry3D (또는 다른 WPF 객체)를 고정한 후에는 한 스레드에서 다른 스레드로 전달할 수 있습니다. 즉, 작업을 병렬화하고 작업자 스레드에서 MeshGeometry3D 개체를 만든 다음이를 고정 된 개체로 UI 스레드에 전달할 수 있습니다.

MeshGeometry3D 개체에서 위치 (및 기타 데이터)를 변경하는 경우도 마찬가지입니다. 기존 위치를 배열 또는 목록에 복사하고 거기에서 데이터를 변경 한 다음 배열에서 위치 컬렉션을 다시 만든 다음 각 개별 위치를 변경하는 것이 더 빠릅니다. MeshGeometry3D를 변경하기 전에 많은 변경 이벤트가 발생하지 않도록 부모 GeometryModel3D에서 연결을 해제해야합니다. 이 작업은 다음과 같이 수행됩니다.

var mesh = parentGeometryModel3D.Geometry; // Save MeshGeometry3D to mesh 
parentGeometryModel3D.Geometry = null; // Disconnect 

// modify the mesh here ... 

parentGeometryModel3D.Geometry = mesh; // Connect the mesh back