여기에 특별한 경우가 있는데, 나는 helix-toolkit이라는 라이브러리를 사용하고 있기 때문에 여기에 나와 있습니다.3D 모델 생성을 병렬화하는 방법은 무엇입니까?
사실 제가 backgroundworker를 사용하여 코드에서 모델 개체를 만드는 것을 병렬 처리하고 싶습니다.
나는 mutlithreading과 UI 요소 작업에 큰 문제가 있음을 알고 있지만 어떻게 든 해결 방법이 있습니다. 나는 Backgroundwoker를 생성하는
첫 번째 파일, Geometry3D 객체를 생성하고 마지막으로 뷰포트에 형상을 결합하는 SetModelGeometry을 호출하는 작업 부하를 분할 :
여기 내 코드의 거친 구조입니다. 두 번째 파일은 바인딩이 수행되는 방법을 보여줍니다.
MainWindow.xaml.cs를
private void Draw_Building()
{
_worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
_worker.DoWork += Draw_Building_DoWork;
_worker.ProgressChanged += DrawBuilding_ProgressChanged;
_worker.RunWorkerCompleted += DrawBuilding_RunWorkerCompleted;
_worker.RunWorkerAsync(10000);
}
private void Draw_Building_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
// returns a list containing Geometry3D objects (created by meshBuilder.ToMeshGeometry3D())
Geometryhandler.Draw_Building(sender, e);
}
private void DrawBuilding_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
StatusProgressBar.Value = e.ProgressPercentage;
var i = (int)e.UserState;
var actualComponent = MyBuildingComponents.First(c => c.Id == i);
LblStatusbarInfo.Text = "Currently meshing element #" + actualComponent.Globalid + " (" +
actualComponent.Objectname + ")";
StatusProgressbarMsg.Text = "Meshing (" + e.ProgressPercentage + " %)";
}
private void DrawBuilding_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
StatusProgressbarMsg.Text = "-";
StatusProgressBar.Value = 0;
LblStatusbarInfo.Text = "Meshing completed.";
Geometry = e.Result as List<MeshIdandGeometry>;
// creates MeshGeometryModel3D objects and binds them to the viewport using the List of Geometries
MainViewModel.SetModelGeometry(Geometry);
}
MainViewModel.cs
public void SetModelGeometry(List<MeshIdandGeometry> geometry)
{
MyModelGeometry = new Element3DCollection();
if (geometry != null)
{
foreach (var mygeometry in geometry)
{
var s = new MeshGeometryModel3D
{
Geometry = mygeometry.Geometry,
Material = mygeometry.Material,
};
this.MyModelGeometry.Add(s);
s.Attach(MyModelViewport.RenderHost);
}
}
this.OnPropertyChanged("MyModelGeometry");
}
순간 내 문제는 다음과 같은 오류 메시지입니다 :
호출 스레드 광고 때문에이 개체에 액세스 할 수 없습니다. ifferent 스레드가 소유하고 있습니다.
ModelGeometry
을 뷰포트에 첨부하려고 할 때 SetModelGeometry
함수에서 발생합니다.
필자는 기하학이 다른 스레드에서 만들어졌으며 지금은 액세스 할 수 없다는 사실에 대해 컴파일러가 불평하고 있다고 생각합니다.
DrawBuilding 함수의 병렬 실행을 손상시키지 않는 해결 방법이 있습니까?
는 편집 :편집 2 : Geometryhandler
에 Draw_Building
방법
Draw_Building
방법의 잘못된 버전을 게시 :
public void Draw_Building(object sender, DoWorkEventArgs e)
{
var geometry = new List<MeshIdandGeometry>();
var standardMaterial = new PhongMaterial()
{
AmbientColor = SharpDX.Color.LightGray,
//DiffuseColor = new Color4(0.35f, 0.35f, 0.35f, 1.0f),
//DiffuseMap = new BitmapImage(new System.Uri(@"Con_Diffuse_2.jpg", System.UriKind.RelativeOrAbsolute)),
//NormalMap = new BitmapImage(new System.Uri(@"Con_Normal_2.jpg", System.UriKind.RelativeOrAbsolute)),
};
var max = _mainWindow.MyBuildingComponents.Count;
var i = 1;
// Loop over building components
foreach (var component in _mainWindow.MyBuildingComponents)
{
//if (i == 5) break;
var component1 = component;
var componentTriangles = _mainWindow.MyTriangles.Where(triangle => triangle.ComponentId == component1.Id);
var meshBuilder = new MeshBuilder(true, true, true);
// Loop over triangles in building element
foreach (var triangle in componentTriangles)
{
var triangle1 = triangle;
var p1 = _mainWindow.MyVertices.Find(
vt => vt.Id == triangle1.PointId1);
var p2 = _mainWindow.MyVertices.Find(
vt => vt.Id == triangle1.PointId2);
var p3 = _mainWindow.MyVertices.Find(
vt => vt.Id == triangle1.PointId3);
if (p1 != null && p2 != null && p3 != null)
{
//meshBuilder.AddTriangle(new Vector3((float)p1.X, (float)p1.Y, (float)p1.Z),
// new Vector3((float)p2.X, (float)p2.Y, (float)p2.Z),
// new Vector3((float)p3.X, (float)p3.Y, (float)p3.Z));
// coordination are switched to match the coordinate system in SharpDX viewport
meshBuilder.AddTriangle(new Vector3(-(float)p1.Y, (float)p1.Z, -(float)p1.X),
new Vector3(-(float)p2.Y, (float)p2.Z, -(float)p2.X),
new Vector3(-(float)p3.Y, (float)p3.Z, -(float)p3.X));
}
}
var mesh = meshBuilder.ToMeshGeometry3D();
var meshandtriangle = new MeshIdandGeometry
{
Id = component1.Id,
Geometry = mesh,
Material = standardMaterial,
};
geometry.Add(meshandtriangle);
i++;
var progressPercentage = Convert.ToInt32(((double)i/max) * 100);
var backgroundWorker = sender as BackgroundWorker;
backgroundWorker?.ReportProgress(progressPercentage, component1.Id);
}
e.Result = geometry;
}
Freeze and Clone 시도 – egse
안녕하세요 egse, 죄송합니다. 지금 귀하의 의견을 보았습니다. 정확히 어떻게 사용합니까? 예를 들어 Media3D.GeometryModel3D 객체에 대해 고정이 구현되었지만 sharpDX 분기가 사용하는 모델 객체에 해당하는 것을 찾지 못했습니다. – Daniel
네, 맞습니다. 그렇다면 오류를 일으키는 기하학이 아니라 재료라고 생각합니다. Geometryhandler.Draw_Building 메서드의 내용을 보여 주면 더 도움이 될 수 있습니다. – egse