Wireframe can be simply created with Ab3d.PowerToys library - check out Wireframe sample under Line3D.
Creating hidden lines can be a very complex task with lots of math.
But it can be also done with a little trick - you create your 3d objects in black or white color and add wireframe to them. So the wireframe that is behind some objects would be hidden by black / white 3d objects.
I have prepared a sample code that you can try (it will be added to the next version of Ab3d.PowerToys).
In the sample that was mentioned before replace the UpdateWireframe method with the following:
Code:
private void UpdateWireframe()
{
bool preserveLineColor;
Color customColor;
if (PreserveColorRadioButton.IsChecked ?? false)
{
preserveLineColor = true;
customColor = Colors.White;
}
else
{
preserveLineColor = false;
switch (CustomColorComboBox.SelectedIndex)
{
case 0:
customColor = Colors.White;
break;
case 1:
customColor = Colors.Red;
break;
default:
case 2:
customColor = Colors.LightBlue;
break;
}
}
// Note that the method is called with preserveLineColor set to true
// This means that the line color will be get from the actual model material (in case it is a SolidColorBrush).
Model3D wireframe = Ab3d.Models.WireframeFactory.CreateWireframe(SceneModel1, 2, preserveLineColor, customColor, SceneCameraViewport2);
WireframeModelGroup1.Children.Clear();
// Use White background
// EmissiveMaterial prevents shading white color
// DiffuseMaterial hides background objects
MaterialGroup newMaterial = new MaterialGroup();
newMaterial.Children.Add(new DiffuseMaterial(Brushes.Black));
newMaterial.Children.Add(new EmissiveMaterial(Brushes.White));
// To use black background simple DiffuseMaterial can be used:
//DiffuseMaterial newMaterial = new DiffuseMaterial(Brushes.Black);
Model3D copiedModel = CopyModel(SceneModel1.Content, newMaterial, null);
WireframeModelGroup1.Children.Add(copiedModel);
WireframeModelGroup1.Children.Add(wireframe);
}
private Model3D CopyModel(Model3D originalModel, Material newMaterial, Material newBackMaterial)
{
Model3D newModel;
if (originalModel is Model3DGroup)
{
Model3DGroup originalModel3DGroup = (Model3DGroup)originalModel;
Model3DGroup newModel3DGroup = new Model3DGroup();
foreach (Model3D childModel3D in originalModel3DGroup.Children)
{
Model3D newChildModel;
newChildModel = CopyModel(childModel3D, newMaterial, newBackMaterial);
newModel3DGroup.Children.Add(newChildModel);
}
newModel = newModel3DGroup;
}
else if (originalModel is GeometryModel3D)
{
GeometryModel3D originalGeometryModel3D = (GeometryModel3D)originalModel;
GeometryModel3D newGeometryModel3D = new GeometryModel3D();
newGeometryModel3D.Geometry = originalGeometryModel3D.Geometry;
if (newMaterial == null)
newGeometryModel3D.Material = originalGeometryModel3D.Material; // Preserve material
else
newGeometryModel3D.Material = newMaterial; // Use newMaterial
if (newBackMaterial == null)
{
// Preserve BackMaterial
if (originalGeometryModel3D.BackMaterial != null)
newGeometryModel3D.BackMaterial = originalGeometryModel3D.BackMaterial;
}
else
{
newGeometryModel3D.BackMaterial = newBackMaterial; // Use newBackMaterial
}
if (originalGeometryModel3D.Transform != null && !originalGeometryModel3D.Transform.Value.IsIdentity)
newGeometryModel3D.Transform = originalGeometryModel3D.Transform;
newModel = newGeometryModel3D;
}
else
{
// TODO: Copy lights, etc.
// For now they are preserved
newModel = originalModel;
}
return newModel;
}
A small problem with this solution is that the background is not seen through the lines as it is blocked by the white 3D objects.
But if you set background in your window to white it would be ok.
Also please note that when showing hidden lines on very complex objects, the performance can become problematic - WPF does not natively support 3D lines, so they are created in Ab3d.PowerToys library with constructing lines with triangles.