public XbimGeometryData TransformBy(XbimMatrix3D matrix)
        {
            XbimMatrix3D t = XbimMatrix3D.FromArray(DataArray2);

            t = XbimMatrix3D.Multiply(t, matrix);
            return(new XbimGeometryData(GeometryLabel, IfcProductLabel, GeometryType, IfcTypeId, ShapeData, t.ToArray(), GeometryHash, StyleLabel, Counter));
        }
        /// <summary>
        /// Builds a windows Matrix3D from an ObjectPlacement
        /// Conversion fo c++ function CartesianTransform::ConvertMatrix3D from CartesianTransform.cpp
        /// </summary>
        /// <param name="objPlacement">IfcObjectPlacement object</param>
        /// <returns>Matrix3D</returns>
        protected XbimMatrix3D ConvertMatrix3D(IfcObjectPlacement objPlacement)
        {
            if (objPlacement is IfcLocalPlacement)
            {
                IfcLocalPlacement locPlacement = (IfcLocalPlacement)objPlacement;
                if (locPlacement.RelativePlacement is IfcAxis2Placement3D)
                {
                    IfcAxis2Placement3D axis3D   = (IfcAxis2Placement3D)locPlacement.RelativePlacement;
                    XbimVector3D        ucsXAxis = new XbimVector3D(axis3D.RefDirection.DirectionRatios[0], axis3D.RefDirection.DirectionRatios[1], axis3D.RefDirection.DirectionRatios[2]);
                    XbimVector3D        ucsZAxis = new XbimVector3D(axis3D.Axis.DirectionRatios[0], axis3D.Axis.DirectionRatios[1], axis3D.Axis.DirectionRatios[2]);
                    ucsXAxis = ucsXAxis.Normalized();
                    ucsZAxis = ucsZAxis.Normalized();
                    XbimVector3D ucsYAxis = XbimVector3D.CrossProduct(ucsZAxis, ucsXAxis);
                    ucsYAxis = ucsYAxis.Normalized();
                    XbimPoint3D ucsCentre = axis3D.Location.XbimPoint3D();

                    XbimMatrix3D ucsTowcs = new XbimMatrix3D(ucsXAxis.X, ucsXAxis.Y, ucsXAxis.Z, 0,
                                                             ucsYAxis.X, ucsYAxis.Y, ucsYAxis.Z, 0,
                                                             ucsZAxis.X, ucsZAxis.Y, ucsZAxis.Z, 0,
                                                             ucsCentre.X, ucsCentre.Y, ucsCentre.Z, 1);
                    if (locPlacement.PlacementRelTo != null)
                    {
                        return(XbimMatrix3D.Multiply(ucsTowcs, ConvertMatrix3D(locPlacement.PlacementRelTo)));
                    }
                    return(ucsTowcs);
                }
                throw new NotImplementedException("Support for Placements other than 3D not implemented");
            }
            throw new NotImplementedException("Support for Placements other than Local not implemented");
        }
Exemple #3
0
        public static void AddElements(this MeshGeometry3D m, IPersistIfcEntity item, XbimMatrix3D wcsTransform)
        {
            var fromModel = item.ModelOf as XbimModel;

            if (fromModel == null || !(item is IfcProduct))
            {
                return;
            }
            switch (fromModel.GeometrySupportLevel)
            {
            case 2:
                var context = new Xbim3DModelContext(fromModel);

                var productShape = context.ShapeInstancesOf((IfcProduct)item)
                                   .Where(s => s.RepresentationType != XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                                   .ToList();
                if (!productShape.Any() && item is IfcFeatureElement)
                {
                    productShape = context.ShapeInstancesOf((IfcProduct)item)
                                   .Where(
                        s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                                   .ToList();
                }

                if (!productShape.Any())
                {
                    return;
                }
                foreach (var shapeInstance in productShape)
                {
                    IXbimShapeGeometryData shapeGeom =
                        context.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                    switch ((XbimGeometryType)shapeGeom.Format)
                    {
                    case XbimGeometryType.PolyhedronBinary:
                        m.Read(shapeGeom.ShapeData,
                               XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                        break;

                    case XbimGeometryType.Polyhedron:
                        m.Read(((XbimShapeGeometry)shapeGeom).ShapeData,
                               XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                        break;
                    }
                }
                break;

            case 1:
                var xm3d        = new XbimMeshGeometry3D();
                var geomDataSet = fromModel.GetGeometryData(item.EntityLabel, XbimGeometryType.TriangulatedMesh);
                foreach (var geomData in geomDataSet)
                {
                    var gd = geomData.TransformBy(wcsTransform);
                    xm3d.Add(gd);
                }
                m.Add(xm3d);
                break;
            }
        }
Exemple #4
0
        /// <summary>
        /// If translation is defined, returns matrix translated by the vector
        /// </summary>
        /// <param name="matrix">Input matrix</param>
        /// <param name="translation">Translation</param>
        /// <returns>Translated matrix</returns>
        private static XbimMatrix3D Translate(XbimMatrix3D matrix, IVector3D translation)
        {
            if (translation == null)
            {
                return(matrix);
            }
            var translationMatrix = XbimMatrix3D.CreateTranslation(translation.X, translation.Y, translation.Z);

            return(XbimMatrix3D.Multiply(matrix, translationMatrix));
        }
        public void GetGeometryFromXbimModel_IFC4(MeshGeometry3D m, IPersistEntity item, XbimMatrix3D wcsTransform)
        {
            if (item.Model == null || !(item is Xbim.Ifc4.Kernel.IfcProduct))
            {
                return;
            }

            var context = new Xbim3DModelContext(item.Model);

            var productShape = context.ShapeInstancesOf((Xbim.Ifc4.Interfaces.IIfcProduct)item)
                               .Where(s => s.RepresentationType != XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                               .ToList();

            if (!productShape.Any() && item is Xbim.Ifc4.Interfaces.IIfcFeatureElement)
            {
                productShape = context.ShapeInstancesOf((Xbim.Ifc4.Interfaces.IIfcProduct)item)
                               .Where(
                    s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                               .ToList();
            }

            if (!productShape.Any())
            {
                return;
            }
            foreach (var shapeInstance in productShape)
            {
                IXbimShapeGeometryData shapeGeom =
                    context.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                switch ((XbimGeometryType)shapeGeom.Format)
                {
                case XbimGeometryType.PolyhedronBinary:
                    m.Read(shapeGeom.ShapeData,
                           XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                    break;

                case XbimGeometryType.Polyhedron:
                    m.Read(((XbimShapeGeometry)shapeGeom).ShapeData,
                           XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                    break;
                }
            }
        }
Exemple #6
0
        public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(XbimModel model, Xbim3DModelContext context, List <Type> exclude = null)
        {
            var tmpOpaquesGroup = new Model3DGroup();

            var retScene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);

            var red   = PrepareMesh(new XbimColour("Red", 1.0, 0.0, 0.0, 0.5));
            var green = PrepareMesh(new XbimColour("Green", 0.0, 1.0, 0.0, 0.5));

            red.WpfModel.SetValue(FrameworkElement.TagProperty, red);
            green.WpfModel.SetValue(FrameworkElement.TagProperty, green);
            red.BeginUpdate();
            green.BeginUpdate();

            tmpOpaquesGroup.Children.Add(red);
            tmpOpaquesGroup.Children.Add(green);

            var i = 0;

            foreach (var shapeInstance in context.ShapeInstances()
                     .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded &&
                            !typeof(IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&&
                                                                                                           * !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/))
            {
                IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                WpfMeshGeometry3D      targetMergeMesh;
                switch (i++ % 2)
                {
                case 0:
                    targetMergeMesh = red;
                    break;

                default:
                    targetMergeMesh = green;
                    break;
                }
                switch ((XbimGeometryType)shapeGeom.Format)
                {
                case XbimGeometryType.Polyhedron:
                    var shapePoly = (XbimShapeGeometry)shapeGeom;
                    targetMergeMesh.Add(
                        shapePoly.ShapeData,
                        shapeInstance.IfcTypeId,
                        shapeInstance.IfcProductLabel,
                        shapeInstance.InstanceLabel,
                        XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom),
                        model.UserDefinedId);
                    break;

                case XbimGeometryType.PolyhedronBinary:
                    targetMergeMesh.Add(
                        shapeGeom.ShapeData,
                        shapeInstance.IfcTypeId,
                        shapeInstance.IfcProductLabel,
                        shapeInstance.InstanceLabel,
                        XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom),
                        model.UserDefinedId
                        );
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            red.EndUpdate();
            green.EndUpdate();

            var mv = new ModelVisual3D {
                Content = tmpOpaquesGroup
            };

            Control.OpaquesVisual3D.Children.Add(mv);
            // Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D();

            return(retScene);
        }
Exemple #7
0
        /// <summary>
        /// This version uses the new Geometry representation
        /// </summary>
        /// <param name="model"></param>
        /// <param name="modelTransform">The transform to place the models geometry in the right place</param>
        /// <param name="opaqueShapes"></param>
        /// <param name="transparentShapes"></param>
        /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param>
        /// <returns></returns>
        public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes,
                                                                     List <Type> exclude = null)
        {
            var excludedTypes = model.DefaultExclusions(exclude);
            var scene         = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);
            var timer         = new Stopwatch();

            timer.Start();
            using (var geomStore = model.GeometryStore)
            {
                using (var geomReader = geomStore.BeginRead())
                {
                    var materialsByStyleId   = new Dictionary <int, WpfMaterial>();
                    var meshesByStyleId      = new Dictionary <int, WpfMeshGeometry3D>();
                    var tmpOpaquesGroup      = new Model3DGroup();
                    var tmpTransparentsGroup = new Model3DGroup();

                    //get a list of all the unique style ids then build their style and mesh
                    var sstyleIds = geomReader.StyleIds;
                    foreach (var styleId in sstyleIds)
                    {
                        var wpfMaterial = GetWpfMaterial(model, styleId);
                        materialsByStyleId.Add(styleId, wpfMaterial);

                        var mg = GetNewStyleMesh(wpfMaterial, tmpTransparentsGroup, tmpOpaquesGroup);
                        meshesByStyleId.Add(styleId, mg);
                    }

                    var shapeInstances = GetShapeInstancesToRender(geomReader, excludedTypes);
                    var tot            = 1;
                    if (ProgressChanged != null)
                    {
                        // only enumerate if there's a need for progress update
                        tot = shapeInstances.Count();
                    }
                    var prog         = 0;
                    var lastProgress = 0;

                    // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&&
                    // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/);
                    foreach (var shapeInstance in shapeInstances)
                    {
                        // logging
                        var currentProgress = 100 * prog++ / tot;
                        if (currentProgress != lastProgress && ProgressChanged != null)
                        {
                            ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals"));
                            lastProgress = currentProgress;
                        }

                        // work out style
                        var styleId = shapeInstance.StyleLabel > 0
                            ? shapeInstance.StyleLabel
                            : shapeInstance.IfcTypeId * -1;

                        if (!materialsByStyleId.ContainsKey(styleId))
                        {
                            // if the style is not available we build one by ExpressType
                            var material2 = GetWpfMaterialByType(model, shapeInstance.IfcTypeId);
                            materialsByStyleId.Add(styleId, material2);

                            var mg = GetNewStyleMesh(material2, tmpTransparentsGroup, tmpOpaquesGroup);
                            meshesByStyleId.Add(styleId, mg);
                        }

                        var boxRep = GetSlicedBoxRepresentation(shapeInstance.BoundingBox);
                        var targetMergeMeshByStyle = meshesByStyleId[styleId];

                        var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform);
                        targetMergeMeshByStyle.Add(
                            boxRep,
                            shapeInstance.IfcTypeId,
                            shapeInstance.IfcProductLabel,
                            shapeInstance.InstanceLabel,
                            transform,
                            (short)model.UserDefinedId);
                    }

                    foreach (var wpfMeshGeometry3D in meshesByStyleId.Values)
                    {
                        wpfMeshGeometry3D.EndUpdate();
                    }
                    if (tmpOpaquesGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpOpaquesGroup
                        };
                        opaqueShapes.Children.Add(mv);
                    }
                    if (tmpTransparentsGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpTransparentsGroup
                        };
                        transparentShapes.Children.Add(mv);
                    }
                }
            }
            Logger.LogDebug("Time to load visual components: {0:F3} seconds", timer.Elapsed.TotalSeconds);

            ProgressChanged?.Invoke(this, new ProgressChangedEventArgs(0, "Ready"));
            return(scene);
        }
        /// <summary>
        /// This version uses the new Geometry representation
        /// </summary>
        /// <param name="model"></param>
        /// <param name="modelTransform">The transform to place the models geometry in the right place</param>
        /// <param name="opaqueShapes"></param>
        /// <param name="transparentShapes"></param>
        /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param>
        /// <returns></returns>
        public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes,
                                                                     List <Type> exclude = null)
        {
            var excludedTypes = model.DefaultExclusions(exclude);

            var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);
            var timer = new Stopwatch();

            timer.Start();
            using (var geomStore = model.GeometryStore)
            {
                using (var geomReader = geomStore.BeginRead())
                {
                    var materialsByStyleId      = new Dictionary <int, WpfMaterial>();
                    var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>();
                    var meshesByStyleId         = new Dictionary <int, WpfMeshGeometry3D>();
                    var tmpOpaquesGroup         = new Model3DGroup();
                    var tmpTransparentsGroup    = new Model3DGroup();

                    //get a list of all the unique style ids then build their style and mesh
                    var sstyleIds = geomReader.StyleIds;
                    foreach (var styleId in sstyleIds)
                    {
                        var wpfMaterial = GetWpfMaterial(model, styleId);
                        materialsByStyleId.Add(styleId, wpfMaterial);

                        var mg = GetNewStyleMesh(wpfMaterial, tmpTransparentsGroup, tmpOpaquesGroup);
                        meshesByStyleId.Add(styleId, mg);
                    }


                    var shapeInstances = geomReader.ShapeInstances
                                         .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded
                                                &&
                                                !excludedTypes.Contains(s.IfcTypeId));

                    var tot          = shapeInstances.Count();
                    var prog         = 0;
                    var lastProgress = 0;



                    // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&&
                    // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/);
                    foreach (var shapeInstance in shapeInstances)
                    {
                        // logging
                        var currentProgress = 100 * prog++ / tot;
                        if (currentProgress != lastProgress && ProgressChanged != null)
                        {
                            ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals"));
                            lastProgress = currentProgress;
                            // Log.DebugFormat("Progress to {0}% time: {1} seconds", lastProgress,  timer.Elapsed.TotalSeconds.ToString("F3"));
                            // Debug.Print("Progress to {0}% time:\t{1} seconds", lastProgress, timer.Elapsed.TotalSeconds.ToString("F3"));
                        }

                        // work out style
                        var styleId = shapeInstance.StyleLabel > 0
                            ? shapeInstance.StyleLabel
                            : shapeInstance.IfcTypeId * -1;

                        if (!materialsByStyleId.ContainsKey(styleId))
                        {
                            // if the style is not available we build one by ExpressType
                            var material2 = GetWpfMaterialByType(model, shapeInstance.IfcTypeId);
                            materialsByStyleId.Add(styleId, material2);

                            var mg = GetNewStyleMesh(material2, tmpTransparentsGroup, tmpOpaquesGroup);
                            meshesByStyleId.Add(styleId, mg);
                        }

                        //GET THE ACTUAL GEOMETRY
                        MeshGeometry3D wpfMesh;
                        //see if we have already read it
                        if (UseMaps && repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh))
                        {
                            var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]);
                            mg.SetValue(FrameworkElement.TagProperty,
                                        new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId));
                            mg.BackMaterial = mg.Material;
                            mg.Transform    =
                                XbimMatrix3D.Multiply(shapeInstance.Transformation,
                                                      modelTransform)
                                .ToMatrixTransform3D();
                            if (materialsByStyleId[styleId].IsTransparent)
                            {
                                tmpTransparentsGroup.Children.Add(mg);
                            }
                            else
                            {
                                tmpOpaquesGroup.Children.Add(mg);
                            }
                        }
                        else //we need to get the shape geometry
                        {
                            IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel);

                            if (UseMaps && shapeGeom.ReferenceCount > 1) //only store if we are going to use again
                            {
                                wpfMesh = new MeshGeometry3D();
                                switch ((XbimGeometryType)shapeGeom.Format)
                                {
                                case XbimGeometryType.PolyhedronBinary:
                                    wpfMesh.Read(shapeGeom.ShapeData);
                                    break;

                                case XbimGeometryType.Polyhedron:
                                    wpfMesh.Read(((XbimShapeGeometry)shapeGeom).ShapeData);
                                    break;
                                }
                                repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh);
                                var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]);
                                mg.SetValue(FrameworkElement.TagProperty,
                                            new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId));
                                mg.BackMaterial = mg.Material;
                                mg.Transform    = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform).ToMatrixTransform3D();
                                if (materialsByStyleId[styleId].IsTransparent)
                                {
                                    tmpTransparentsGroup.Children.Add(mg);
                                }
                                else
                                {
                                    tmpOpaquesGroup.Children.Add(mg);
                                }
                            }
                            else //it is a one off, merge it with shapes of same style
                            {
                                var targetMergeMeshByStyle = meshesByStyleId[styleId];
                                if (shapeGeom.Format != (byte)XbimGeometryType.PolyhedronBinary)
                                {
                                    continue;
                                }
                                var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform);
                                targetMergeMeshByStyle.Add(
                                    shapeGeom.ShapeData,
                                    shapeInstance.IfcTypeId,
                                    shapeInstance.IfcProductLabel,
                                    shapeInstance.InstanceLabel, transform,
                                    (short)model.UserDefinedId);
                            }
                        }
                    }

                    foreach (var wpfMeshGeometry3D in meshesByStyleId.Values)
                    {
                        wpfMeshGeometry3D.EndUpdate();
                    }
                    //}
                    if (tmpOpaquesGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpOpaquesGroup
                        };
                        opaqueShapes.Children.Add(mv);
                        // Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D();
                    }
                    if (tmpTransparentsGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpTransparentsGroup
                        };
                        transparentShapes.Children.Add(mv);
                        //if (Control.ModelBounds.IsEmpty) Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D();
                        //else Control.ModelBounds.Union(mv.Content.Bounds.ToXbimRect3D());
                    }
                }
            }
            Log.DebugFormat("Time to load visual components: {0} seconds", timer.Elapsed.TotalSeconds.ToString("F3"));

            if (ProgressChanged != null)
            {
                ProgressChanged(this, new ProgressChangedEventArgs(0, "Ready"));
            }
            return(scene);
        }
Exemple #9
0
        public static XbimMeshGeometry3D GetMesh(this XbimModel xbimModel, IEnumerable <IPersistIfcEntity> items, XbimMatrix3D wcsTransform)
        {
            var m = new XbimMeshGeometry3D();

            if (xbimModel.GeometrySupportLevel == 1)
            {
                // this is what happens for version 1 of the engine
                //
                foreach (var item in items)
                {
                    var fromModel = item.ModelOf as XbimModel;
                    if (fromModel == null)
                    {
                        continue;
                    }
                    var geomDataSet = fromModel.GetGeometryData(item.EntityLabel, XbimGeometryType.TriangulatedMesh);
                    foreach (var geomData in geomDataSet)
                    {
                        // todo: add guidance to the TransformBy method so that users can understand how to stop using it (it's marked absolete)
                        geomData.TransformBy(wcsTransform);
                        m.Add(geomData, xbimModel.UserDefinedId);
                    }
                }
            }
            else
            {
                // this is what happens for version 2 of the engine
                //
                foreach (var item in items)
                {
                    var fromModel = item.ModelOf as XbimModel;
                    if (fromModel == null || !(item is IfcProduct))
                    {
                        continue;
                    }
                    var context = new Xbim3DModelContext(fromModel);

                    var productShape =
                        context.ShapeInstancesOf((IfcProduct)item)
                        .Where(s => s.RepresentationType != XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                        .ToList();     // this also returns shapes of voids
                    foreach (var shapeInstance in productShape)
                    {
                        IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                        switch ((XbimGeometryType)shapeGeom.Format)
                        {
                        case XbimGeometryType.PolyhedronBinary:
                            m.Read(shapeGeom.ShapeData,
                                   XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                            break;

                        case XbimGeometryType.Polyhedron:
                            m.Read(((XbimShapeGeometry)shapeGeom).ShapeData,
                                   XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                            break;
                        }
                    }
                }
            }
            return(m);
        }
Exemple #10
0
        /// <summary>
        /// Exports a gltf file from a meshed model
        /// </summary>
        /// <param name="model">The model needs to have the geometry meshes already cached</param>
        /// <param name="exclude">The types of elements that are going to be omitted (e.g. ifcSpaces).</param>
        /// <param name="EntityLebels">Only entities in the collection are exported; if null exports the whole model</param>
        /// <returns></returns>
        public gltf.Gltf BuildInstancedScene(IModel model, XbimMatrix3D overallTransform, List <Type> exclude = null, HashSet <int> EntityLebels = null)
        {
            Init();
            Dictionary <int, ShapeComponentIds> geometries = new Dictionary <int, ShapeComponentIds>();

            // this needs a previously meshed xbim file.
            //
            var s = new Stopwatch();

            s.Start();
            int    iCnt          = 0;
            Random r             = new Random();
            var    excludedTypes = DefaultExclusions(model, exclude);

            using (var geomStore = model.GeometryStore)
                using (var geomReader = geomStore.BeginRead())
                {
                    // process the materials and styles
                    var sstyleIds = geomReader.StyleIds;
                    foreach (var styleId in sstyleIds)
                    {
                        PrepareStyleMaterial(model, styleId);
                    }
                    int productLabel   = 0;
                    var shapeInstances = GetShapeInstancesToRender(geomReader, excludedTypes, EntityLebels);
                    // foreach (var shapeInstance in shapeInstances.OrderBy(x=>x.IfcProductLabel))
                    gltf.Mesh targetMesh = null;
                    foreach (var shapeInstance in shapeInstances.OrderBy(x => x.IfcProductLabel))
                    {
                        if (CustomFilter != null)
                        {
                            var skip = CustomFilter(shapeInstance.IfcProductLabel, model);
                            if (skip)
                            {
                                continue;
                            }
                        }

                        // we start with a shape instance and then load its geometry.

                        // a product (e.g. wall or window) in the scene returns:
                        // - a node
                        //   - pointing to a mesh, with a transform
                        // - 1 mesh
                        //   - with as many mesh primitives as needed to render the different parts
                        //   - pointers to the a material and accessors as needed
                        // - 3 accessors per primitive
                        //   - vertices, normals, indices
                        // - bufferviews can be reused by different accessors
                        // - data in the buffer, of course

                        if (productLabel != shapeInstance.IfcProductLabel)
                        {
                            // need new product

                            // create node
                            var nodeIndex = _nodes.Count;
                            var entity    = model.Instances[shapeInstance.IfcProductLabel] as IIfcProduct;
                            if (entity == null)
                            { // fire error here.
                            }
                            var tnode = new gltf.Node();
                            tnode.Name = entity.Name + $" #{entity.EntityLabel}";

                            // instance transformation needs to be expressed in meters
                            //
                            var inModelTransf = XbimMatrix3D.Copy(shapeInstance.Transformation);
                            inModelTransf.OffsetX /= model.ModelFactors.OneMeter;
                            inModelTransf.OffsetY /= model.ModelFactors.OneMeter;
                            inModelTransf.OffsetZ /= model.ModelFactors.OneMeter;

                            // overalltransform is already expressed in meters
                            var tMat = XbimMatrix3D.Multiply(inModelTransf, overallTransform);

                            tnode.Matrix = tMat.ToFloatArray();

                            // create mesh
                            var meshIndex = _meshes.Count;
                            targetMesh = new gltf.Mesh
                            {
                                Name = $"Instance {productLabel}"
                            };

                            // link node to mesh
                            tnode.Mesh = meshIndex;

                            // add all to lists
                            _nodes.Add(tnode);
                            _meshes.Add(targetMesh);
                        }

                        // now the geometry
                        //
                        IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                        if (shapeGeom.Format != (byte)XbimGeometryType.PolyhedronBinary)
                        {
                            continue;
                        }

                        // work out colour id;
                        // the colour is associated with the instance, not the geometry.
                        // positives are styles, negatives are types
                        var colId = shapeInstance.StyleLabel > 0
                        ? shapeInstance.StyleLabel
                        : shapeInstance.IfcTypeId * -1;

                        int materialIndex;
                        if (!styleDic.TryGetValue(colId, out materialIndex))
                        {
                            // if the style is not available we build one by ExpressType
                            materialIndex = PrepareTypeMaterial(model, shapeInstance.IfcTypeId);
                            styleDic.Add(colId, materialIndex);
                        }

                        // note: at a first investigation it looks like the shapeInstance.Transformation is the same for all shapes of the same product

                        if (shapeGeom.ReferenceCount > 1)
                        {
                            // retain the information to reuse the map multiple times
                            //

                            // if g is not found in the dictionary then build it and add it
                            ShapeComponentIds components;
                            if (!geometries.TryGetValue(shapeGeom.ShapeLabel, out components))
                            {
                                // mesh
                                var xbimMesher = new XbimMesher();
                                xbimMesher.AddMesh(shapeGeom.ShapeData);

                                components = AddGeom(
                                    xbimMesher.PositionsAsSingleList(model.ModelFactors.OneMeter),
                                    xbimMesher.Indices,
                                    xbimMesher.NormalsAsSingleList()
                                    );
                                geometries.Add(shapeGeom.ShapeLabel, components);
                            }

                            if (components != null)
                            {
                                // var arr = GetTransformInMeters(model, shapeInstance);
                                AddComponentsToMesh(targetMesh, components, materialIndex);
                            }
                        }
                        else
                        {
                            // repeat the geometry only once
                            //
                            var xbimMesher = new XbimMesher();
                            xbimMesher.AddMesh(shapeGeom.ShapeData);
                            // var trsf = GetTransformInMeters(model, shapeInstance);
                            var components = AddGeom(
                                xbimMesher.PositionsAsSingleList(model.ModelFactors.OneMeter),
                                xbimMesher.Indices,
                                xbimMesher.NormalsAsSingleList()
                                );
                            AddComponentsToMesh(targetMesh, components, materialIndex);
                        }
                        iCnt++;
                        if (iCnt % 100 == 0)
                        {
                            Debug.WriteLine($"added {iCnt} elements in {s.ElapsedMilliseconds}ms.");
                        }
                    }
                }
            Debug.WriteLine($"added {iCnt} elements in {s.ElapsedMilliseconds}ms.");

            return(Build());
        }
        XbimScene <WpfMeshGeometry3D, WpfMaterial> ILayerStyler.BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <Type> exclude)
        {
            var excludedTypes   = model.DefaultExclusions(exclude);
            var tmpOpaquesGroup = new Model3DGroup();
            var retScene        = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);


            if (_model.Instances == null || !_model.Instances.Any())
            {
                return(retScene);
            }

            // define colours
            var colours = new Dictionary <LayerGroup, XbimColour>();

            colours.Add(LayerGroup.Green, new XbimColour("Green", 0.0, 1.0, 0.0, 0.5));
            colours.Add(LayerGroup.Red, new XbimColour("Red", 1.0, 0.0, 0.0, 0.5));
            colours.Add(LayerGroup.Amber, new XbimColour("Amber", .5, 0.5, .5, .8)); // actually grey

            // prepare meshes
            //

            var meshes = new List <WpfMeshGeometry3D>(); // this list gets added to the scene at the end.

            // this dictionary holds the list of meshes that are currently used, as they are filled (in size),
            // new ones get replaced
            //
            var meshDic = new Dictionary <LayerGroup, WpfMeshGeometry3D>();

            foreach (var group in colours.Keys)
            {
                var newItem = PrepareMesh(colours[group]);
                meshDic.Add(group, newItem);
                meshes.Add(newItem);
            }

            foreach (var mesh in meshes)
            {
                mesh.WpfModel.SetValue(FrameworkElement.TagProperty, mesh);
                mesh.BeginUpdate();
                tmpOpaquesGroup.Children.Add(mesh);
            }

            using (var geomStore = model.GeometryStore)
            {
                using (var geomReader = geomStore.BeginRead())
                {
                    var shapeInstances = geomReader.ShapeInstances
                                         .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded
                                                &&
                                                !excludedTypes.Contains(s.IfcTypeId));
                    foreach (var shapeInstance in shapeInstances)
                    {
                        var ent = _model.Instances[shapeInstance.IfcProductLabel];
                        var grp = GetLayerGroup(ent);
                        if (grp == LayerGroup.Null)
                        {
                            continue;
                        }
                        if (!UseAmber && grp == LayerGroup.Amber)
                        {
                            continue;
                        }

                        WpfMeshGeometry3D targetMergeMesh;
                        meshDic.TryGetValue(grp, out targetMergeMesh);

                        if (targetMergeMesh == null)
                        {
                            continue;
                        }

                        // replace target mesh beyond suggested size
                        // https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/maximize-wpf-3d-performance
                        //
                        if (targetMergeMesh.PositionCount > 20000
                            ||
                            targetMergeMesh.TriangleIndexCount > 60000
                            )
                        {
                            // end current mesh
                            targetMergeMesh.EndUpdate();

                            // prepare new one and add to the list
                            var replace = PrepareMesh(colours[grp]);
                            meshes.Add(replace);

                            // swap mesh in dicionary and for this loop
                            meshDic[grp]    = replace;
                            targetMergeMesh = replace;

                            // prepare in output
                            replace.WpfModel.SetValue(FrameworkElement.TagProperty, replace);
                            replace.BeginUpdate();
                            tmpOpaquesGroup.Children.Add(replace);
                        }

                        IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                        if (shapeGeom.Format == (byte)XbimGeometryType.PolyhedronBinary)
                        {
                            var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation,
                                                                  modelTransform);
                            targetMergeMesh.Add(
                                shapeGeom.ShapeData,
                                shapeInstance.IfcTypeId,
                                shapeInstance.IfcProductLabel,
                                shapeInstance.InstanceLabel, transform,
                                (short)model.UserDefinedId);
                        }
                    }
                }
            }
            foreach (var mesh in meshDic.Values)
            {
                mesh.EndUpdate();
            }
            if (!tmpOpaquesGroup.Children.Any())
            {
                return(retScene);
            }
            var mv = new ModelVisual3D {
                Content = tmpOpaquesGroup
            };

            opaqueShapes.Children.Add(mv);
            return(retScene);
        }
Exemple #12
0
        /// <summary>
        /// This version uses the new Geometry representation
        /// </summary>
        /// <param name="model"></param>
        /// <param name="context"></param>
        /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param>
        /// <returns></returns>
        public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(XbimModel model, Xbim3DModelContext context,
                                                                     List <Type> exclude = null)
        {
            var excludedTypes = new HashSet <short>();

            if (exclude == null)
            {
                exclude = new List <Type>()
                {
                    typeof(IfcSpace)
                    // , typeof(IfcFeatureElement)
                }
            }
            ;
            foreach (var excludedT in exclude)
            {
                var ifcT = IfcMetaData.IfcType(excludedT);
                foreach (var exIfcType in ifcT.NonAbstractSubTypes.Select(IfcMetaData.IfcType))
                {
                    excludedTypes.Add(exIfcType.TypeId);
                }
            }

            var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);

            if (context == null)
            {
                return(scene);
            }

            //get a list of all the unique styles
            var styles = new Dictionary <int, WpfMaterial>();
            var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>();
            var styleMeshSets           = new Dictionary <int, WpfMeshGeometry3D>();
            var tmpOpaquesGroup         = new Model3DGroup();
            var tmpTransparentsGroup    = new Model3DGroup();

            var sstyles = context.SurfaceStyles();


            foreach (var style in sstyles)
            {
                var wpfMaterial = new WpfMaterial();
                wpfMaterial.CreateMaterial(style);
                styles.Add(style.DefinedObjectId, wpfMaterial);
                var mg = new WpfMeshGeometry3D(wpfMaterial, wpfMaterial);
                mg.WpfModel.SetValue(FrameworkElement.TagProperty, mg);
                styleMeshSets.Add(style.DefinedObjectId, mg);
                mg.BeginUpdate();
                if (style.IsTransparent)
                {
                    tmpTransparentsGroup.Children.Add(mg);
                }
                else
                {
                    tmpOpaquesGroup.Children.Add(mg);
                }
            }

            if (!styles.Any())
            {
                return(scene);               //this should always return something
            }
            var shapeInstances = context.ShapeInstances()
                                 .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded
                                        &&
                                        !excludedTypes.Contains(s.IfcTypeId));

            // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&&
            // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/);
            foreach (var shapeInstance in shapeInstances)
            {
                var styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1;

                //GET THE ACTUAL GEOMETRY
                MeshGeometry3D wpfMesh;
                //see if we have already read it
                if (repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh))
                {
                    var mg = new GeometryModel3D(wpfMesh, styles[styleId]);
                    mg.SetValue(FrameworkElement.TagProperty,
                                new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId));
                    mg.BackMaterial = mg.Material;
                    mg.Transform    =
                        XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom).ToMatrixTransform3D();
                    if (styles[styleId].IsTransparent)
                    {
                        tmpTransparentsGroup.Children.Add(mg);
                    }
                    else
                    {
                        tmpOpaquesGroup.Children.Add(mg);
                    }
                }
                else //we need to get the shape geometry
                {
                    IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel);

                    if (shapeGeom.ReferenceCount > 1) //only store if we are going to use again
                    {
                        wpfMesh = new MeshGeometry3D();
                        switch ((XbimGeometryType)shapeGeom.Format)
                        {
                        case XbimGeometryType.PolyhedronBinary:
                            wpfMesh.Read(shapeGeom.ShapeData);
                            break;

                        case XbimGeometryType.Polyhedron:
                            wpfMesh.Read(((XbimShapeGeometry)shapeGeom).ShapeData);
                            break;
                        }

                        repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh);
                        var mg = new GeometryModel3D(wpfMesh, styles[styleId]);
                        mg.SetValue(FrameworkElement.TagProperty,
                                    new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId));
                        mg.BackMaterial = mg.Material;
                        mg.Transform    =
                            XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom).ToMatrixTransform3D();
                        if (styles[styleId].IsTransparent)
                        {
                            tmpTransparentsGroup.Children.Add(mg);
                        }
                        else
                        {
                            tmpOpaquesGroup.Children.Add(mg);
                        }
                    }
                    else //it is a one off, merge it with shapes of a similar material
                    {
                        var targetMergeMeshByStyle = styleMeshSets[styleId];

                        switch ((XbimGeometryType)shapeGeom.Format)
                        {
                        case XbimGeometryType.Polyhedron:
                            // var shapePoly = (XbimShapeGeometry)shapeGeom;
                            var asString = Encoding.UTF8.GetString(shapeGeom.ShapeData.ToArray());
                            targetMergeMeshByStyle.Add(
                                asString,
                                shapeInstance.IfcTypeId,
                                shapeInstance.IfcProductLabel,
                                shapeInstance.InstanceLabel,
                                XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom),
                                model.UserDefinedId);
                            break;

                        case XbimGeometryType.PolyhedronBinary:
                            var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom);
                            targetMergeMeshByStyle.Add(
                                shapeGeom.ShapeData,
                                shapeInstance.IfcTypeId,
                                shapeInstance.IfcProductLabel,
                                shapeInstance.InstanceLabel, transform,
                                model.UserDefinedId);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                }
            }
            foreach (var wpfMeshGeometry3D in styleMeshSets.Values)
            {
                wpfMeshGeometry3D.EndUpdate();
            }
            //}
            if (tmpOpaquesGroup.Children.Any())
            {
                var mv = new ModelVisual3D();
                mv.Content = tmpOpaquesGroup;
                Control.OpaquesVisual3D.Children.Add(mv);
                // Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D();
            }
            if (tmpTransparentsGroup.Children.Any())
            {
                var mv = new ModelVisual3D();
                mv.Content = tmpTransparentsGroup;
                Control.TransparentsVisual3D.Children.Add(mv);
                //if (Control.ModelBounds.IsEmpty) Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D();
                //else Control.ModelBounds.Union(mv.Content.Bounds.ToXbimRect3D());
            }
            return(scene);
        }
Exemple #13
0
        private void WriteGeometry(JsonWriter writer)
        {
            XbimMatrix3D globalTrans = GetGlobalModelTransform();
            //write out the material nodes and then the instances for each material
            Dictionary <int, XbimTexture> styles = _context.SurfaceStyles().ToDictionary(s => s.DefinedObjectId);

            foreach (var instanceGroup in _context.ShapeInstancesGroupByStyle())
            {
                if (!instanceGroup.Any())
                {
                    continue;                       //skip emmpty instances;
                }
                int         styleId = instanceGroup.Key;
                XbimTexture style   = styles[styleId];
                writer.WriteStartObject(); //Material node
                {
                    writer.WritePropertyName("type"); writer.WriteValue("material");
                    writer.WritePropertyName("id"); writer.WriteValue("M" + styleId);
                    writer.WritePropertyName("color");
                    writer.WriteStartObject(); //begin color
                    {
                        writer.WritePropertyName("r"); writer.WriteValue(style.ColourMap[0].Red);
                        writer.WritePropertyName("g"); writer.WriteValue(style.ColourMap[0].Green);
                        writer.WritePropertyName("b"); writer.WriteValue(style.ColourMap[0].Blue);
                    } writer.WriteEndObject(); //end color
                    writer.WritePropertyName("alpha"); writer.WriteValue(style.ColourMap[0].Alpha);
                    //all instances of this style
                    writer.WritePropertyName("nodes"); //beginning of the instance nodes
                    writer.WriteStartArray();
                    foreach (var shapeInstance in instanceGroup)
                    {
                        writer.WriteStartObject();                                //start of instance transform
                        {
                            if (_maps.Contains(shapeInstance.ShapeGeometryLabel)) //it is a reference
                            {
                                //write the transform
                                writer.WritePropertyName("type"); //geometry node
                                writer.WriteValue("matrix");
                                writer.WritePropertyName("id");
                                writer.WriteValue("I" + shapeInstance.InstanceLabel);
                                writer.WritePropertyName("elements");
                                XbimMatrix3D m = XbimMatrix3D.Multiply(shapeInstance.Transformation, globalTrans);
                                WriteMatrix(writer, m);
                                writer.WritePropertyName("nodes"); //beginning of the instance nodes
                                writer.WriteStartArray();
                                //write the map
                                writer.WriteStartObject();            //start of map
                                {
                                    writer.WritePropertyName("type"); //geometry node
                                    writer.WriteValue("geometry");
                                    writer.WritePropertyName("coreId");
                                    writer.WriteValue("L" + shapeInstance.ShapeGeometryLabel);
                                } writer.WriteEndObject(); //end of map
                                writer.WriteEndArray();    //end of instance tranform nodes
                            }
                            else //write the actual geometry
                            {
                                writer.WritePropertyName("type");      //geometry node
                                writer.WriteValue("geometry");
                                writer.WritePropertyName("primitive"); //primitive: "
                                writer.WriteValue("triangles");
                                writer.WritePropertyName("id");
                                writer.WriteValue("I" + shapeInstance.InstanceLabel);
                                WriteShapeGeometry(writer, _context.ShapeGeometry(shapeInstance), XbimMatrix3D.Multiply(shapeInstance.Transformation, globalTrans));
                            }
                        } writer.WriteEndObject(); //end of instance transform
                    }
                    writer.WriteEndArray();        //end of instance transform nodes
                } writer.WriteEndObject();         // end of the material node
            }
        }
        XbimScene <WpfMeshGeometry3D, WpfMaterial> ILayerStyler.BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <Type> exclude)
        {
            var excludedTypes   = model.DefaultExclusions(exclude);
            var tmpOpaquesGroup = new Model3DGroup();
            var retScene        = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);
            var meshes          = new List <WpfMeshGeometry3D>();

            if (_discriminator == null)
            {
                _discriminator = new VisualDiscriminator(_window.Doc);
            }

            if (_model.Instances == null || !_model.Instances.Any())
            {
                return(retScene);
            }

            var red   = PrepareMesh(_colourFail); meshes.Add(red);
            var green = PrepareMesh(_colourPass); meshes.Add(green);
            var blue  = PrepareMesh(_colourNa); meshes.Add(blue);
            var amber = PrepareMesh(_colourWarning); meshes.Add(amber);

            foreach (var mesh in meshes)
            {
                mesh.WpfModel.SetValue(FrameworkElement.TagProperty, mesh);
                mesh.BeginUpdate();
                tmpOpaquesGroup.Children.Add(mesh);
            }

            using (var geomStore = model.GeometryStore)
            {
                using (var geomReader = geomStore.BeginRead())
                {
                    var shapeInstances = geomReader.ShapeInstances
                                         .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded
                                                &&
                                                !excludedTypes.Contains(s.IfcTypeId));
                    foreach (var shapeInstance in shapeInstances)
                    {
                        var ent = _model.Instances[shapeInstance.IfcProductLabel];
                        var grp = _discriminator.GetLayerGroup(ent);

                        if (grp == VisualDiscriminator.LayerGroup.Null)
                        {
                            continue;
                        }
                        if (!UseBlue && grp == VisualDiscriminator.LayerGroup.Blue)
                        {
                            continue;
                        }
                        if (!UseAmber && grp == VisualDiscriminator.LayerGroup.Amber)
                        {
                            continue;
                        }

                        WpfMeshGeometry3D targetMergeMesh = null;

                        switch (grp)
                        {
                        case VisualDiscriminator.LayerGroup.Red:
                            targetMergeMesh = red;
                            break;

                        case VisualDiscriminator.LayerGroup.Green:
                            targetMergeMesh = green;
                            break;

                        case VisualDiscriminator.LayerGroup.Blue:
                            targetMergeMesh = blue;
                            break;

                        case VisualDiscriminator.LayerGroup.Amber:
                            targetMergeMesh = amber;
                            break;
                        }
                        if (targetMergeMesh == null)
                        {
                            continue;
                        }

                        IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                        if (shapeGeom.Format == (byte)XbimGeometryType.PolyhedronBinary)
                        {
                            var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation,
                                                                  modelTransform);
                            targetMergeMesh.Add(
                                shapeGeom.ShapeData,
                                shapeInstance.IfcTypeId,
                                shapeInstance.IfcProductLabel,
                                shapeInstance.InstanceLabel, transform,
                                (short)model.UserDefinedId);
                        }
                    }
                }
            }
            foreach (var mesh in meshes)
            {
                mesh.EndUpdate();
            }
            if (!tmpOpaquesGroup.Children.Any())
            {
                return(retScene);
            }
            var mv = new ModelVisual3D {
                Content = tmpOpaquesGroup
            };

            opaqueShapes.Children.Add(mv);
            // no transparents are present
            //if (tmpTransparentsGroup.Children.Any())
            //{
            //    var mv = new ModelVisual3D { Content = tmpTransparentsGroup };
            //    transparentShapes.Children.Add(mv);
            //}
            return(retScene);
        }
        /// <summary>
        /// This version uses the new Geometry representation
        /// </summary>
        /// <param name="model"></param>
        /// <param name="modelTransform">The transform to place the models geometry in the right place</param>
        /// <param name="opaqueShapes"></param>
        /// <param name="transparentShapes"></param>
        /// <param name="isolateInstances">List of instances to be isolated</param>
        /// <param name="hideInstances">List of instances to be hidden</param>
        /// <param name="excludeTypes">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param>
        /// <returns></returns>
        public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform,
                                                                     ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <IPersistEntity> isolateInstances = null, List <IPersistEntity> hideInstances = null, List <Type> excludeTypes = null)
        {
            var excludedTypes   = model.DefaultExclusions(excludeTypes);
            var onlyInstances   = isolateInstances?.Where(i => i.Model == model).ToDictionary(i => i.EntityLabel);
            var hiddenInstances = hideInstances?.Where(i => i.Model == model).ToDictionary(i => i.EntityLabel);

            var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);
            var timer = new Stopwatch();

            timer.Start();
            using (var geomStore = model.GeometryStore)
            {
                using (var geomReader = geomStore.BeginRead())
                {
                    // we are keeping the style to decide if a new element needs to be transparent.
                    //
                    var materialsByStyleId      = new Dictionary <int, WpfMaterial>();
                    var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>();
                    var tmpOpaquesGroup         = new Model3DGroup();
                    var tmpTransparentsGroup    = new Model3DGroup();

                    //get a list of all the unique style ids then build their style and mesh
                    //
                    var sstyleIds = geomReader.StyleIds;
                    foreach (var styleId in sstyleIds)
                    {
                        var wpfMaterial = GetWpfMaterial(model, styleId);
                        materialsByStyleId.Add(styleId, wpfMaterial);
                    }

                    var shapeInstances = GetShapeInstancesToRender(geomReader, excludedTypes);
                    var tot            = 1;
                    if (ProgressChanged != null)
                    {
                        // only enumerate if there's a need for progress update
                        tot = shapeInstances.Count();
                    }
                    var prog         = 0;
                    var lastProgress = 0;

                    // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&&
                    // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/);
                    //
                    foreach (var shapeInstance in shapeInstances
                             .Where(s => null == onlyInstances || onlyInstances.Count == 0 || onlyInstances.Keys.Contains(s.IfcProductLabel))
                             .Where(s => null == hiddenInstances || hiddenInstances.Count == 0 || !hiddenInstances.Keys.Contains(s.IfcProductLabel)))
                    {
                        int id = shapeInstance.IfcProductLabel; //LINKS TO ACTUAL ELEMENT


                        ShadedElement el = elements[id];

                        var i = model.Instances[id];
                        // logging
                        var currentProgress = 100 * prog++ / tot;
                        if (currentProgress != lastProgress && ProgressChanged != null)
                        {
                            ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals"));
                            lastProgress = currentProgress;
                        }

                        // work out style
                        var styleId = shapeInstance.StyleLabel > 0
                            ? shapeInstance.StyleLabel
                            : shapeInstance.IfcTypeId * -1;

                        WpfMaterial selectedMaterial;
                        if (!materialsByStyleId.TryGetValue(styleId, out selectedMaterial))
                        {
                            // if the style is not available we build one by ExpressType
                            selectedMaterial = GetWpfMaterialByType(model, shapeInstance.IfcTypeId);
                            materialsByStyleId.Add(styleId, selectedMaterial);
                        }
                        int colorIndex = (int)el.currCriticality;

                        selectedMaterial = new WpfMaterial(colsPerCriticality[colorIndex]);

                        //GET THE ACTUAL GEOMETRY
                        MeshGeometry3D wpfMesh;
                        //see if we have already read it
                        if (!repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh))
                        {
                            IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                            if ((XbimGeometryType)shapeGeom.Format != XbimGeometryType.PolyhedronBinary)
                            {
                                continue;
                            }
                            wpfMesh = new MeshGeometry3D();
                            wpfMesh.Read(shapeGeom.ShapeData);
                            if (shapeGeom.ReferenceCount > 1) //only store if we are going to use again
                            {
                                repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh);
                            }
                        }
                        var mg = new GeometryModel3D(wpfMesh, selectedMaterial);
                        mg.BackMaterial = mg.Material;

                        mg.SetValue(FrameworkElement.TagProperty,
                                    new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId));
                        mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform).ToMatrixTransform3D();
                        if (materialsByStyleId[styleId].IsTransparent)
                        {
                            tmpTransparentsGroup.Children.Add(mg);
                        }
                        else
                        {
                            tmpOpaquesGroup.Children.Add(mg);
                        }
                    }

                    if (tmpOpaquesGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpOpaquesGroup
                        };
                        opaqueShapes.Children.Add(mv);
                    }
                    if (tmpTransparentsGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpTransparentsGroup
                        };
                        transparentShapes.Children.Add(mv);
                    }
                }
            }
            Logger.LogDebug("Time to load visual components: {0:F3} seconds", timer.Elapsed.TotalSeconds);

            ProgressChanged?.Invoke(this, new ProgressChangedEventArgs(0, "Ready"));
            return(scene);
        }
        /// <summary>
        /// This version uses the new Geometry representation
        /// </summary>
        /// <param name="model"></param>
        /// <param name="modelTransform">The transform to place the models geometry in the right place</param>
        /// <param name="opaqueShapes"></param>
        /// <param name="transparentShapes"></param>
        /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param>
        /// <returns></returns>
        public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes,
                                                                     List <Type> exclude = null)
        {
            var excludedTypes = model.DefaultExclusions(exclude);

            var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model);
            var timer = new Stopwatch();

            timer.Start();
            using (var geomStore = model.GeometryStore)
            {
                using (var geomReader = geomStore.BeginRead())
                {
                    var materialsByStyleId      = new Dictionary <int, WpfMaterial>();
                    var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>();
                    var meshesByStyleId         = new Dictionary <int, WpfMeshGeometry3D>();
                    var tmpOpaquesGroup         = new Model3DGroup();
                    var tmpTransparentsGroup    = new Model3DGroup();

                    //get a list of all the unique style ids then build their style and mesh
                    var sstyleIds = geomReader.StyleIds;
                    foreach (var styleId in sstyleIds)
                    {
                        var wpfMaterial = GetWpfMaterial(model, styleId);
                        materialsByStyleId.Add(styleId, wpfMaterial);

                        var mg = GetNewStyleMesh(wpfMaterial, tmpTransparentsGroup, tmpOpaquesGroup);
                        meshesByStyleId.Add(styleId, mg);
                    }

                    var shapeInstances = GetShapeInstancesToRender(geomReader, excludedTypes);
                    var tot            = 1;
                    if (ProgressChanged != null)
                    {
                        // only enumerate if there's a need for progress update
                        tot = shapeInstances.Count();
                    }
                    var prog         = 0;
                    var lastProgress = 0;

                    // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&&
                    // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/);
                    foreach (var shapeInstance in shapeInstances)
                    {
                        // logging
                        var currentProgress = 100 * prog++ / tot;
                        if (currentProgress != lastProgress && ProgressChanged != null)
                        {
                            ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals"));
                            lastProgress = currentProgress;
                        }

                        // work out style
                        var styleId = shapeInstance.StyleLabel > 0
                            ? shapeInstance.StyleLabel
                            : shapeInstance.IfcTypeId * -1;

                        if (!materialsByStyleId.ContainsKey(styleId))
                        {
                            // if the style is not available we build one by ExpressType
                            var material2 = GetWpfMaterialByType(model, shapeInstance.IfcTypeId);
                            materialsByStyleId.Add(styleId, material2);

                            var mg = GetNewStyleMesh(material2, tmpTransparentsGroup, tmpOpaquesGroup);
                            meshesByStyleId.Add(styleId, mg);
                        }

                        //GET THE ACTUAL GEOMETRY
                        MeshGeometry3D wpfMesh;
                        //see if we have already read it
                        if (UseMaps && repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh))
                        {
                            var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]);
                            mg.SetValue(FrameworkElement.TagProperty,
                                        new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId));
                            mg.BackMaterial = mg.Material;
                            mg.Transform    =
                                XbimMatrix3D.Multiply(shapeInstance.Transformation,
                                                      modelTransform)
                                .ToMatrixTransform3D();
                            if (materialsByStyleId[styleId].IsTransparent)
                            {
                                tmpTransparentsGroup.Children.Add(mg);
                            }
                            else
                            {
                                tmpOpaquesGroup.Children.Add(mg);
                            }
                        }
                        else //we need to get the shape geometry
                        {
                            IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel);

                            if (UseMaps && shapeGeom.ReferenceCount > 1) //only store if we are going to use again
                            {
                                wpfMesh = new MeshGeometry3D();
                                switch ((XbimGeometryType)shapeGeom.Format)
                                {
                                case XbimGeometryType.PolyhedronBinary:
                                    wpfMesh.Read(shapeGeom.ShapeData);
                                    break;

                                case XbimGeometryType.Polyhedron:
                                    wpfMesh.Read(((XbimShapeGeometry)shapeGeom).ShapeData);
                                    break;
                                }
                                repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh);
                                var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]);
                                mg.SetValue(FrameworkElement.TagProperty,
                                            new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId));
                                mg.BackMaterial = mg.Material;
                                mg.Transform    = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform).ToMatrixTransform3D();
                                if (materialsByStyleId[styleId].IsTransparent)
                                {
                                    tmpTransparentsGroup.Children.Add(mg);
                                }
                                else
                                {
                                    tmpOpaquesGroup.Children.Add(mg);
                                }
                            }
                            else //it is a one off, merge it with shapes of same style
                            {
                                var targetMergeMeshByStyle = meshesByStyleId[styleId];

                                // replace target mesh beyond suggested size
                                // https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/maximize-wpf-3d-performance
                                //
                                if (targetMergeMeshByStyle.PositionCount > 20000
                                    ||
                                    targetMergeMeshByStyle.TriangleIndexCount > 60000
                                    )
                                {
                                    targetMergeMeshByStyle.EndUpdate();
                                    var replace = GetNewStyleMesh(materialsByStyleId[styleId], tmpTransparentsGroup, tmpOpaquesGroup);
                                    meshesByStyleId[styleId] = replace;
                                    targetMergeMeshByStyle   = replace;
                                }
                                // end replace

                                if (shapeGeom.Format != (byte)XbimGeometryType.PolyhedronBinary)
                                {
                                    continue;
                                }
                                var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform);
                                targetMergeMeshByStyle.Add(
                                    shapeGeom.ShapeData,
                                    shapeInstance.IfcTypeId,
                                    shapeInstance.IfcProductLabel,
                                    shapeInstance.InstanceLabel, transform,
                                    (short)model.UserDefinedId);
                            }
                        }
                    }

                    foreach (var wpfMeshGeometry3D in meshesByStyleId.Values)
                    {
                        wpfMeshGeometry3D.EndUpdate();
                    }
                    if (tmpOpaquesGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpOpaquesGroup
                        };
                        opaqueShapes.Children.Add(mv);
                    }
                    if (tmpTransparentsGroup.Children.Any())
                    {
                        var mv = new ModelVisual3D {
                            Content = tmpTransparentsGroup
                        };
                        transparentShapes.Children.Add(mv);
                    }
                }
            }
            Log.DebugFormat("Time to load visual components: {0:F3} seconds", timer.Elapsed.TotalSeconds);

            ProgressChanged?.Invoke(this, new ProgressChangedEventArgs(0, "Ready"));
            return(scene);
        }
        public BimStore3DModel Load(string fileName)
        {
            var bimStoreItems = new Dictionary <IPersistEntity, List <Tuple <MeshGeometry3D, MaterialModel, XbimMatrix3D> > > (); //ID - ifcProductLabel

            var ifcModel = IfcStore.Open(fileName, null, null,
                                         (progress, state) => { reportProgress?.Invoke(progress, state); },
                                         XbimDBAccess.Exclusive);

            //Prepare
            var modelPosition = new XbimModelPositioning(ifcModel);
            var context       = new Xbim3DModelContext(ifcModel);

            context.CreateContext();

            //Clear materials
            MaterialManager.Clear();

            var materialsByStyleId = new Dictionary <int, MaterialModel>();

            var excludedTypes = GenerateDefaultExclusions(ifcModel, DefaultExcludedTypes);

            using (var geometryStore = ifcModel.ReferencingModel.GeometryStore)
            {
                using (var geometryReader = geometryStore.BeginRead())
                {
                    var shapeInstances = GetShapeInstancesToRender(geometryReader, excludedTypes);

                    foreach (var shapeInstance in shapeInstances)
                    {
                        #region Material

                        var styleId = shapeInstance.StyleLabel > 0
                            ? shapeInstance.StyleLabel
                            : shapeInstance.IfcTypeId * -1;

                        MaterialModel material;
                        if (!materialsByStyleId.ContainsKey(styleId))
                        {
                            material = MaterialModelCreator.Create(ifcModel, shapeInstance.IfcTypeId);
                            materialsByStyleId.Add(styleId, material);
                            MaterialManager.Add(material);
                        }
                        else
                        {
                            material = materialsByStyleId[styleId];
                        }

                        #endregion

                        #region Geometry

                        IXbimShapeGeometryData shapeGeometry =
                            geometryReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel);

                        var geometry3D = new MeshGeometry3D();
                        switch ((XbimGeometryType)shapeGeometry.Format)
                        {
                        case XbimGeometryType.PolyhedronBinary:
                            geometry3D.Read(shapeGeometry.ShapeData);
                            break;

                        case XbimGeometryType.Polyhedron:
                            geometry3D.Read(((XbimShapeGeometry)shapeGeometry).ShapeData);
                            break;
                        }

                        #endregion

                        var ifcProduct = ifcModel.Model.Instances.FirstOrDefault(i => i.EntityLabel == shapeInstance.IfcProductLabel);

                        if (ifcProduct != null)
                        {
                            if (!bimStoreItems.ContainsKey(ifcProduct))
                            {
                                bimStoreItems.Add(ifcProduct, new List <Tuple <MeshGeometry3D, MaterialModel, XbimMatrix3D> >(new []
                                {
                                    new Tuple <MeshGeometry3D, MaterialModel, XbimMatrix3D>(geometry3D, material, XbimMatrix3D.Multiply(modelPosition.Transform, shapeInstance.Transformation)),
                                }));
                            }
                            else
                            {
                                bimStoreItems[ifcProduct].Add(new Tuple <MeshGeometry3D, MaterialModel, XbimMatrix3D>(geometry3D, material, XbimMatrix3D.Multiply(modelPosition.Transform, shapeInstance.Transformation)));
                            }
                        }
                    }
                }
            }

            //Generate model
            var bimStore3D = new BimStore3DModel(context.Model as IfcStore);

            foreach (var bimStoreItem in bimStoreItems)
            {
                bimStore3D.Add(
                    new BimStoreItem3DModel(bimStoreItem.Key,
                                            new List <BimGeometry3DModel>(
                                                bimStoreItem.Value.Select(x =>
                                                                          new BimGeometry3DModel(
                                                                              x.Item1.ToMeshModel(),
                                                                              x.Item2,
                                                                              x.Item3.ToMatrix3D())))));
            }

            return(bimStore3D);
        }