03-18-2013, 03:49 PM
MultiMaterialBox is more complicated 3D objects because it is actually a Model3DGroup with 6 difference GeometryModel3D - one for each material.
Below I am posting the code to create MultiMaterialBox (taken from Ab3d.Models.Model3DFactory).
You should change the code so that you will create 6 PlaneMesh3D objects to create MeshGeometryes - as with the previous sample on this post you need to create them with size = 1 and at (0, 0, 0). Than freeze the meshes.
After that you should create GeometryModel3D-s with different materials, group them into Model3DGroup and apply transformation to Model3DGroup to scale and position the group.
I would also advice you that you use only one instance of Material for the same material (this means that you should use as little Material instances as possible - so all Orange materials should be in one Material instace). You can also freeze the material (you should freeze as many things as possible).
This will surely increase performance a lot, but I am not sure if the performance for 5000 MultiMaterialBox will be really good.
Below I am posting the code to create MultiMaterialBox (taken from Ab3d.Models.Model3DFactory).
You should change the code so that you will create 6 PlaneMesh3D objects to create MeshGeometryes - as with the previous sample on this post you need to create them with size = 1 and at (0, 0, 0). Than freeze the meshes.
After that you should create GeometryModel3D-s with different materials, group them into Model3DGroup and apply transformation to Model3DGroup to scale and position the group.
I would also advice you that you use only one instance of Material for the same material (this means that you should use as little Material instances as possible - so all Orange materials should be in one Material instace). You can also freeze the material (you should freeze as many things as possible).
This will surely increase performance a lot, but I am not sure if the performance for 5000 MultiMaterialBox will be really good.
Code:
/// <summary>
/// Creates a 3D Box model where each side can have its own material.
/// </summary>
/// <remarks>
/// <para>
/// The <b>CreateMultiMaterialBox</b> creates a 3D box where each side of the box can have its own material.
/// </para>
/// <para>
/// To create a 3D box where all sides have the same material use <see cref="CreateBox(Point3D, Size3D, int, int, int, Material)"/> method.
/// </para>
/// </remarks>
/// <param name="centerPosition">box center position</param>
/// <param name="size">size of the box</param>
/// <param name="xCellsCount">number of cells in x direction</param>
/// <param name="yCellsCount">number of cells in y direction</param>
/// <param name="zCellsCount">number of cells in z direction</param>
/// <param name="topMaterial">top material</param>
/// <param name="bottomMaterial">bottom material</param>
/// <param name="leftMaterial">left material</param>
/// <param name="rightMaterial">right material</param>
/// <param name="frontMaterial">front material</param>
/// <param name="backMaterial">back material</param>
/// <param name="isBackMaterialSet">is true the BackMaterial for each side is set to the same value as Material.</param>
/// <returns>3D Box model as Model3DGroup</returns>
public static Model3DGroup CreateMultiMaterialBox(Point3D centerPosition, Size3D size,
int xCellsCount, int yCellsCount, int zCellsCount,
Material topMaterial, Material bottomMaterial,
Material leftMaterial, Material rightMaterial,
Material frontMaterial, Material backMaterial,
bool isBackMaterialSet)
{
Size3D halfSize;
Model3DGroup boxGroup;
PlaneMesh3D onePlaneMesh;
GeometryModel3D oneGeometryModel3D;
halfSize = new Size3D(size.X / 2, size.Y / 2, size.Z / 2);
boxGroup = new Model3DGroup();
// Top side
onePlaneMesh = new PlaneMesh3D(new Point3D(centerPosition.X, centerPosition.Y + halfSize.Y, centerPosition.Z),
new Vector3D(0, 1, 0), // normal: up
new Vector3D(0, 0, -1), // heightDirection: into the screen
new Size(size.X, size.Z),
xCellsCount, zCellsCount);
oneGeometryModel3D = new GeometryModel3D();
oneGeometryModel3D.Geometry = onePlaneMesh.Geometry;
oneGeometryModel3D.Material = topMaterial;
if (isBackMaterialSet)
oneGeometryModel3D.BackMaterial = topMaterial;
boxGroup.Children.Add(oneGeometryModel3D);
// Bottom side
onePlaneMesh = new PlaneMesh3D(new Point3D(centerPosition.X, centerPosition.Y - halfSize.Y, centerPosition.Z),
new Vector3D(0, -1, 0), // normal: down
new Vector3D(0, 0, -1), // heightDirection: into the screen
new Size(size.X, size.Z),
xCellsCount, zCellsCount);
oneGeometryModel3D = new GeometryModel3D();
oneGeometryModel3D.Geometry = onePlaneMesh.Geometry;
oneGeometryModel3D.Material = bottomMaterial;
if (isBackMaterialSet)
oneGeometryModel3D.BackMaterial = bottomMaterial;
boxGroup.Children.Add(oneGeometryModel3D);
// Left side
onePlaneMesh = new PlaneMesh3D(new Point3D(centerPosition.X - halfSize.X, centerPosition.Y, centerPosition.Z),
new Vector3D(-1, 0, 0), // normal: to the left
new Vector3D(0, 1, 0), // heightDirection: up
new Size(size.Z, size.Y),
zCellsCount, yCellsCount);
oneGeometryModel3D = new GeometryModel3D();
oneGeometryModel3D.Geometry = onePlaneMesh.Geometry;
oneGeometryModel3D.Material = leftMaterial;
if (isBackMaterialSet)
oneGeometryModel3D.BackMaterial = leftMaterial;
boxGroup.Children.Add(oneGeometryModel3D);
// Right side
onePlaneMesh = new PlaneMesh3D(new Point3D(centerPosition.X + halfSize.X, centerPosition.Y, centerPosition.Z),
new Vector3D(1, 0, 0), // normal: to the right
new Vector3D(0, 1, 0), // heightDirection: up
new Size(size.Z, size.Y),
zCellsCount, yCellsCount);
oneGeometryModel3D = new GeometryModel3D();
oneGeometryModel3D.Geometry = onePlaneMesh.Geometry;
oneGeometryModel3D.Material = rightMaterial;
if (isBackMaterialSet)
oneGeometryModel3D.BackMaterial = rightMaterial;
boxGroup.Children.Add(oneGeometryModel3D);
// Front side
onePlaneMesh = new PlaneMesh3D(new Point3D(centerPosition.X, centerPosition.Y, centerPosition.Z + halfSize.Z),
new Vector3D(0, 0, 1), // normal: away from screen
new Vector3D(0, 1, 0), // heightDirection: up
new Size(size.X, size.Y),
xCellsCount, yCellsCount);
oneGeometryModel3D = new GeometryModel3D();
oneGeometryModel3D.Geometry = onePlaneMesh.Geometry;
oneGeometryModel3D.Material = frontMaterial;
if (isBackMaterialSet)
oneGeometryModel3D.BackMaterial = frontMaterial;
boxGroup.Children.Add(oneGeometryModel3D);
// Back side
onePlaneMesh = new PlaneMesh3D(new Point3D(centerPosition.X, centerPosition.Y, centerPosition.Z - halfSize.Z),
new Vector3D(0, 0, -1), // normal: away from screen
new Vector3D(0, 1, 0), // heightDirection: up
new Size(size.X, size.Y),
xCellsCount, yCellsCount);
oneGeometryModel3D = new GeometryModel3D();
oneGeometryModel3D.Geometry = onePlaneMesh.Geometry;
oneGeometryModel3D.Material = backMaterial;
if (isBackMaterialSet)
oneGeometryModel3D.BackMaterial = backMaterial;
boxGroup.Children.Add(oneGeometryModel3D);
return boxGroup;
}
Andrej Benedik

