WireFrame & Hidden Functionalty on Loaded File
#1
Hi

I am trying to add a WireFrime view and Hidden view(Hidden Lines) functionality on the loaded file. But I am not able to find any help to implement this feature.

Please let me know is there any way to add such feature.

Thanks,
Yogender Tomar
#2
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.
Andrej Benedik
#3
Hi

Thanks very much for the solution.
I am creating WireFrame Model using "WireframeFactory" function and then modifying the Opaque Property = 0, of all the Models, to make the models transparent. I am doing this to see only WireFrame model, But with some of the 3ds files I am not able to apply the Opaque=0.

I am also attaching the 2 snaps with Correct-WireFrame and Incorrect-WireFrame files.
"Correct.WireFrame" --> Contains the required WireFrame I need. All the objects are transparent.
"InCorrect-WireFrame" --> This file does not contain complete WireFrame, as Opaqueness is not removed from all the objects.

Please let me know what I am doing wrong in this code to make the objects transparent. Any idea or clue will be appreciated.

Code:
public void ToggleWireFrame()
        {
            Model3DGroup objectHead = newReader3ds.NamedObjects[Reader3ds.RootModelGroupName] as Model3DGroup;
            this.m_myViewPort.MainModelGroup.Children.Clear();
            
            double nOpacity = 1.0;
            DiffuseMaterial material;
            material = new DiffuseMaterial();
            bool bWireFrame = false;
            if (m_WireframeModel == null)
            {
                m_WireframeModel = Ab3d.Models.WireframeFactory.CreateWireframe(objectHead, 1, false, System.Windows.Media.Color.FromRgb(255, 255, 255), this.m_myViewPort.MainViewport3ds);
                this.m_myViewPort.MainModelGroup.Children.Add(m_WireframeModel);
                nOpacity = 0.0;
                material.Brush = new SolidColorBrush(System.Windows.Media.Color.FromRgb(39, 126, 147));
                material.Brush.Opacity = nOpacity;
            }
            //Apply the transparency
            try
            {
                if (objectHead is Model3DGroup)
                {
                    ApplyRecusrsion(objectHead, material, bWireFrame);
                }
            }
            catch (System.Exception e)
            {
            }
        }

        //Remove Opaqueness from all the objects recursivly
        private void ApplyRecusrsion(object objectHead, DiffuseMaterial material)
        {
            Model3DCollection modelCol = ((Model3DGroup)objectHead).Children;
            foreach (object o in modelCol)
            {
                if (o is Model3DGroup)
                {
                    ApplyRecusrsion(o, material);
                }
                else if (o is GeometryModel3D)
                {
                    //Set the new transparent material
                    ((GeometryModel3D)o).Material = material;
                    }
                }
            }

        }
Thanks Very Much
Yogender Tomar

(02-15-2011, 04:52 PM)abenedik Wrote: 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.

[attachment=12][attachment=14][attachment=12][attachment=14]


Attached Files Thumbnail(s)
       
#4
Hm, this really looks strange.

Is it possible that those three objects have BackMaterial set? Try to set the BackMaterial to null in your ApplyRecusrsion method.
Andrej Benedik
#5
Wow! It worked.

Thanks Very Much!:) For such a Prompt Reply!
  


Forum Jump:


Users browsing this thread:
1 Guest(s)