Exemplo n.º 1
0
        private void Extract(string inputFilePath, string outputFolderPath, CancellationToken token)
        {
            using (var fc = new FileCleaner())
            {
                var idsFilePath = Path.GetTempFileName();
                fc.AddFile(idsFilePath);

                if (token.IsCancellationRequested)
                {
                    return;
                }
                if (ExtractShell(_ExtractShellCLI, inputFilePath, idsFilePath, token))
                {
                    //如果抽壳成功,则从原始模型中把外壳提取出来另存
                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    using (var doc = SvfDocument.LoadFrom(inputFilePath))
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }
                        doc.Extract(idsFilePath, outputFolderPath, token);
                    }
                }
            }
        }
Exemplo n.º 2
0
        CompareModel(SvfDocument svfbase, SvfDocument svfincr)
        {
            var baseNodes = new Dictionary <string, SvfNode>();

            foreach (var node in svfbase)
            {
                if (node.Children?.Count == 0 &&
                    node.Fragments?.Count > 0 &&
                    string.IsNullOrEmpty(node.ExternalId) == false)
                {
                    baseNodes[node.ExternalId] = node;
                }
            }

            var elementsAdded = new HashSet <string>();

            var elementsUnmodified = new HashSet <string>();

            var elementsModified = new HashSet <string>();

            var elementsDeleted = new HashSet <string>();

            foreach (var node in svfincr)
            {
                if (node.Children?.Count == 0 &&
                    node.Fragments?.Count > 0 &&
                    string.IsNullOrEmpty(node.ExternalId) == false)
                {
                    if (baseNodes.TryGetValue(node.ExternalId, out SvfNode baseNode))
                    {
                        if (baseNode.Fragments.Equals(node.Fragments))
                        {
                            elementsUnmodified.Add(node.ExternalId); //unmdified
                        }
                        else
                        {
                            elementsModified.Add(node.ExternalId); //modified
                        }

                        baseNodes.Remove(node.ExternalId);
                    }
                    else
                    {
                        elementsAdded.Add(node.ExternalId); //added
                    }
                }
            }

            foreach (var p in baseNodes.Keys)
            {
                elementsDeleted.Add(p); //deleted
            }

            baseNodes.Clear();

            return(elementsUnmodified, elementsAdded, elementsDeleted, elementsModified);
        }
Exemplo n.º 3
0
        private void ConvertSvfToGltf(string svfFilePath, string gltfFilePath, bool allowExtractShell, GltfOption options, CancellationToken token)
        {
            using (var fc = new FileCleaner())
            {
                #region 抽取外壳

                if (allowExtractShell)
                {
                    var idsFilePath = Path.GetTempFileName();
                    fc.AddFile(idsFilePath);

                    if (token.IsCancellationRequested)
                    {
                        return;
                    }
                    if (ExtractShell(_ExtractShellCLI, svfFilePath, idsFilePath, token))
                    {
                        //如果抽壳成功,则从原始模型中把外壳提取出来

                        var tempFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                        FileSystemUtility.CreateDirectory(tempFolder);
                        fc.AddFolder(tempFolder);

                        if (token.IsCancellationRequested)
                        {
                            return;
                        }
                        using (var doc = SvfDocument.LoadFrom(svfFilePath))
                        {
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }
                            if (doc.Extract(idsFilePath, tempFolder, token))
                            {
                                svfFilePath = tempFolder;   //将 Svf -> glTF 的输入源替换成已经抽壳的模型
                            }
                        }
                    }
                }

                #endregion

                if (token.IsCancellationRequested)
                {
                    return;
                }
                GltfExtension.ConvertToGltf(svfFilePath, gltfFilePath, options, token);
            }
        }
Exemplo n.º 4
0
        private void btnGenerate_Click(object sender, EventArgs e)
        {
            using (var session = App.CreateSession())
            {
                if (session.IsValid == false)
                {
                    LicenseSession.ShowLicenseDialog(session, this);
                    return;
                }

                using (new ProgressHelper(this, @"Generating Diff Model ..."))
                {
                    try
                    {
                        var sw = Stopwatch.StartNew();

                        #region setup materials

                        var matUnmodified = new Material
                        {
                            Color        = Vector3D.FromColor(0xffffff), //Darker: Vector3D.FromColor(0x101010)
                            Transparent  = 0.95,
                            Reflectivity = 0
                        };

                        var matAdd = new Material
                        {
                            Color = Vector3D.FromColor(Color.GreenYellow)
                        };

                        var matDelete = new Material
                        {
                            Color = Vector3D.FromColor(Color.Red)
                        };

                        var matModifiedBefore = new Material
                        {
                            Color       = Vector3D.FromColor(Color.Orange),
                            Transparent = 0.5
                        };

                        var matModifiedAfter = new Material
                        {
                            Color = Vector3D.FromColor(Color.Aqua),
                        };

                        #endregion

                        var baseModelPath = txtBaseModel.Text;
                        var incrModelPath = txtIncrementModel.Text;
                        var diffModelPath = txtDiffModel.Text;

                        var svfbase = baseModelPath.EndsWith(@"zip")
                            ? SvfDocument.LoadFromZipFile(baseModelPath)
                            : SvfDocument.LoadFromSvfFile(baseModelPath);

                        var svfincr = incrModelPath.EndsWith(@"zip")
                            ? SvfDocument.LoadFromZipFile(incrModelPath)
                            : SvfDocument.LoadFromSvfFile(incrModelPath);

                        var compareResult = CompareModel(svfbase, svfincr);

                        var svfdiff = new SvfDocument();
                        svfdiff.Model.Name = @"Diff Model";
                        svfdiff.Metadata   = svfbase.Metadata;

                        var nodeUnmodified = svfdiff.Model.Children.CreateNode();
                        nodeUnmodified.Name = @"Unmodified";

                        var nodeAdded = svfdiff.Model.Children.CreateNode();
                        nodeAdded.Name = @"Added";

                        var nodeDeleted = svfdiff.Model.Children.CreateNode();
                        nodeDeleted.Name = @"Deleted";

                        var nodeModifiedBefore = svfdiff.Model.Children.CreateNode();
                        nodeModifiedBefore.Name = @"Modified Before";

                        var nodeModifiedAfter = svfdiff.Model.Children.CreateNode();
                        nodeModifiedAfter.Name = @"Modified After";

                        svfbase.EnumerateNodes(node =>
                        {
                            if (node.Children?.Count == 0 &&
                                node.Fragments?.Count > 0 &&
                                string.IsNullOrEmpty(node.ExternalId) == false)
                            {
                                if (compareResult.Unmodified.Remove(node.ExternalId))
                                {
                                    ImportNodeWithPath(nodeUnmodified, node, svfbase.Model, matUnmodified);
                                }
                                else if (compareResult.Deleted.Remove(node.ExternalId))
                                {
                                    ImportNodeWithPath(nodeDeleted, node, svfbase.Model, matDelete);
                                }
                                else if (compareResult.Modified.Contains(node.ExternalId))
                                {
                                    var targetNode =
                                        ImportNodeWithPath(nodeModifiedBefore, node, svfbase.Model, matModifiedBefore);
                                    targetNode.ExternalId += @"_Before";
                                }
                            }
                        }, svfbase.Model);

                        svfincr.EnumerateNodes(node =>
                        {
                            if (node.Children?.Count == 0 &&
                                node.Fragments?.Count > 0 &&
                                string.IsNullOrEmpty(node.ExternalId) == false)
                            {
                                if (compareResult.Added.Remove(node.ExternalId))
                                {
                                    ImportNodeWithPath(nodeAdded, node, svfincr.Model, matAdd);
                                }
                                else if (compareResult.Modified.Remove(node.ExternalId))
                                {
                                    ImportNodeWithPath(nodeModifiedAfter, node, svfincr.Model, matModifiedAfter);
                                }
                            }
                        }, svfincr.Model);

                        svfdiff.SaveToFolder(diffModelPath, true);
                        svfdiff.Dispose();

                        svfbase.Dispose();
                        svfincr.Dispose();

                        ProgressHelper.Close();
                        var message = $@"Generate Diff Model Success! (duration: {sw.Elapsed})";
                        MessageBox.Show(this, message, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        ProgressHelper.Close();
                        MessageBox.Show(this, ex.ToString(), Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
        }
Exemplo n.º 5
0
        private void btnMerge_Click(object sender, EventArgs e)
        {
            var models = new List <SvfModel>();

            foreach (SvfModel item in svfModelBindingSource)
            {
                if (item == null)
                {
                    continue;
                }
                models.Add(item);
            }
            if (models.Count < 1)
            {
                MessageBox.Show(this, @"The source model list is empty!", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (string.IsNullOrEmpty(txtOutput.Text))
            {
                MessageBox.Show(this, @"Please Select Output Path!", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            using (var session = LicenseConfig.Create())
            {
                if (session.IsValid == false)
                {
                    LicenseConfig.ShowDialog(session, this);
                    return;
                }

                using (new ProgressHelper(this, @"Merging ..."))
                {
                    try
                    {
                        var sw        = Stopwatch.StartNew();
                        var targetDoc = new SvfDocument();
                        var docs      = new List <SvfDocument>();
                        var init      = false;
                        foreach (var model in models)
                        {
                            var doc = model.ModelPath.EndsWith(@"zip")
                                ? SvfDocument.LoadFromZipFile(model.ModelPath)
                                : SvfDocument.LoadFromSvfFile(model.ModelPath);
                            doc.Model.Name = model.ModelTitle;

                            if (!init)
                            {
                                targetDoc.Metadata = doc.Metadata.Clone();
                                init = true;
                            }

                            if (targetDoc.Metadata.DefaultCamera == null && doc.Metadata.DefaultCamera != null)
                            {
                                targetDoc.Metadata.DefaultCamera = doc.Metadata.DefaultCamera.Clone();
                            }

                            var transform = Metadata
                                            .GetUnitScaleTransform(doc.Metadata.Units, targetDoc.Metadata.Units)
                                            .Multiply(doc.Metadata.RefPointTransform);

                            targetDoc.Model.Children.ImportNode(doc.Model, transform);

                            doc.Reset();
                            docs.Add(doc);
                        }

                        if (targetDoc.Metadata.DefaultCamera != null)
                        {
                            targetDoc.Metadata.DefaultCamera.AutoFit = true;
                        }

                        targetDoc.SaveToFolder(txtOutput.Text, true);
                        targetDoc.Dispose();

                        foreach (var doc in docs)
                        {
                            doc.Dispose();
                        }
                        docs.Clear();

                        ProgressHelper.Close();
                        var message = $@"Merge Success! (duration: {sw.Elapsed})";
                        MessageBox.Show(this, message, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        ProgressHelper.Close();
                        MessageBox.Show(this, ex.ToString(), Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
        }
Exemplo n.º 6
0
        private void btnMerge_Click(object sender, EventArgs e)
        {
            var models = new List <SvfModel>();

            foreach (SvfModel item in svfModelBindingSource)
            {
                if (item == null)
                {
                    continue;
                }
                models.Add(item);
            }
            if (models.Count < 1)
            {
                MessageBox.Show(this, @"The source model list is empty!", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (string.IsNullOrEmpty(txtOutput.Text))
            {
                MessageBox.Show(this, @"Please Select Output Path!", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            var mode = (int)((cbPositioningMode.SelectedItem as ItemValue <PositioningMode>)?.Value ?? PositioningMode.BySharedCoordinates);

            using (var session = LicenseConfig.Create())
            {
                if (session.IsValid == false)
                {
                    LicenseConfig.ShowDialog(session, this);
                    return;
                }

                using (new ProgressHelper(this, @"Merging ..."))
                {
                    try
                    {
                        var sw        = Stopwatch.StartNew();
                        var targetDoc = new SvfDocument();
                        var docs      = new List <SvfDocument>();
                        var init      = false;
                        foreach (var model in models)
                        {
                            var doc = model.ModelPath.EndsWith(@"zip")
                                ? SvfDocument.LoadFromZipFile(model.ModelPath)
                                : SvfDocument.LoadFromSvfFile(model.ModelPath);
                            doc.Model.Name = model.ModelTitle;

                            if (!init)
                            {
                                targetDoc.Metadata = doc.Metadata.Clone();
                                init = true;
                            }

                            if (targetDoc.Metadata.DefaultCamera == null && doc.Metadata.DefaultCamera != null)
                            {
                                targetDoc.Metadata.DefaultCamera = doc.Metadata.DefaultCamera.Clone();
                            }

                            Transform transform;
                            switch (mode)
                            {
                            case 1:     //原点对原点
                            {
                                transform = Metadata
                                            .GetUnitScaleTransform(doc.Metadata.Units, targetDoc.Metadata.Units);
                                break;
                            }

                            case 2:     //项目基点对项目基点
                            {
                                transform = Metadata
                                            .GetUnitScaleTransform(doc.Metadata.Units, targetDoc.Metadata.Units)
                                            .Multiply(doc.Metadata.PrjPointTransform);
                                break;
                            }

                            case 3:     //中心对中心
                            {
                                var box = doc.Metadata.WorldBoundingBox;
                                if (box == null || box.Empty())
                                {
                                    transform = Metadata
                                                .GetUnitScaleTransform(doc.Metadata.Units, targetDoc.Metadata.Units);
                                }
                                else
                                {
                                    var offset = new Vector3D();
                                    offset.X  = -(box.Max.X + box.Min.X) / 2;
                                    offset.Y  = -(box.Max.Y + box.Min.Y) / 2;
                                    offset.Z  = -(box.Max.Z + box.Min.Z) / 2;
                                    transform = Metadata
                                                .GetUnitScaleTransform(doc.Metadata.Units, targetDoc.Metadata.Units)
                                                .Multiply(Transform.GetTranslation(offset));
                                }
                                break;
                            }

                            case 0:     //通过共享坐标
                            default:
                            {
                                transform = Metadata
                                            .GetUnitScaleTransform(doc.Metadata.Units, targetDoc.Metadata.Units)
                                            .Multiply(doc.Metadata.RefPointTransform);
                                break;
                            }
                            }

                            targetDoc.Model.Children.ImportNode(doc.Model, transform);

                            doc.Reset();
                            docs.Add(doc);
                        }

                        if (targetDoc.Metadata.DefaultCamera != null)
                        {
                            targetDoc.Metadata.DefaultCamera.AutoFit = true;
                        }

                        targetDoc.SaveToFolder(txtOutput.Text, true);
                        targetDoc.Dispose();

                        foreach (var doc in docs)
                        {
                            doc.Dispose();
                        }
                        docs.Clear();

                        ProgressHelper.Close();
                        var message = $@"Merge Success! (duration: {sw.Elapsed})";
                        MessageBox.Show(this, message, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        ProgressHelper.Close();
                        MessageBox.Show(this, ex.ToString(), Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
            }
        }
Exemplo n.º 7
0
        private SvfDocument CreateTarget(SvfDocument initDoc, int mode, out Transform targetTransform)
        {
            targetTransform = Transform.GetIdentity();

            var doc  = new SvfDocument();
            var meta = doc.Metadata = initDoc.Metadata.Clone(true);

            #region 整理转换矩阵元数据

            if (meta.RefPointTransform == null)
            {
                if (meta.RefPointLMV != null && meta.AngleToTrueNorth.HasValue)
                {
                    var angle    = meta.AngleToTrueNorth.Value * Math.PI / 180.0;
                    var rotation = new QuaternionD().SetFromEuler(new EulerD(0.0, 0.0, angle));
                    meta.RefPointTransform = Transform.GetRotationTranslation(rotation, meta.RefPointLMV);
                }
                else
                {
                    meta.RefPointTransform = Transform.GetIdentity();
                }
            }
            if (meta.PrjPointTransform == null)
            {
                meta.PrjPointTransform = Transform.GetIdentity();
            }

            #endregion

            switch (mode)
            {
            case 1:     //原点对原点
            {
                //合模时使用原始内部坐标系,直接使用即可;
                break;
            }

            case 2:     //项目基点对项目基点
            {
                //合模时使用项目坐标系,最后结果需要转换为内部坐标系
                targetTransform = meta.PrjPointTransform.Inverse() ?? Transform.GetIdentity();
                break;
            }

            case 3:     //中心对中心
            {
                //合模时使用内部坐标系,但因为原点做了偏移,最后结果需要修正回来;
                var box = doc.Metadata.WorldBoundingBox;
                if (box != null && !box.IsEmpty())
                {
                    var offset = new Vector3D();
                    offset.X        = -(box.Max.X + box.Min.X) / 2;
                    offset.Y        = -(box.Max.Y + box.Min.Y) / 2;
                    offset.Z        = -(box.Max.Z + box.Min.Z) / 2;
                    targetTransform = Transform.GetTranslation(offset.MultiplyScalar(-1));
                }
                break;
            }

            case 0:     //通过共享坐标
            default:
            {
                //合模时使用共享坐标系,最后结果需要转换为内部坐标系
                targetTransform = meta.RefPointTransform.Inverse() ?? Transform.GetIdentity();
                break;
            }
            }

            return(doc);
        }