示例#1
0
        private static JTNode XMLElement2Node(XmlNode referenceElement, Dictionary <string, ZipArchiveEntry> partEntries)
        {
            var referenceElementAttributes = referenceElement.Attributes;

            var node = new JTNode()
            {
                ID         = int.Parse(referenceElementAttributes["id"].Value),
                Number     = referenceElementAttributes["name"].Value,
                Attributes = ExtractAttributes(referenceElement.ChildNodes)
            };

            if (node.Attributes.ContainsKey("V_Name"))
            {
                node.Name = node.Attributes["V_Name"].ToString();
            }

            if (referenceElement.Name == "ReferenceRep")
            {
                var partFileName = referenceElement.Attributes["associatedFile"].Value.Replace("urn:3DXML:", "");

                if (partEntries.ContainsKey(partFileName))
                {
                    using (var partFileStream = partEntries[partFileName].Open())
                    {
                        node.GeometricSets = GetGeometricSets(partFileStream);
                    }
                }
            }

            return(node);
        }
示例#2
0
文件: JTNode.cs 项目: MazvydasT/JSJT
        private SegmentHeader GetMetaDataSegmentHeader(JTNode node)
        {
            if (uniqueMetaDataSegmentHeaders.ContainsKey(node))
            {
                return(uniqueMetaDataSegmentHeaders[node]);
            }

            var attributes = node.Attributes;

            if (attributes.Count == 0)
            {
                return(null);
            }

            var keys   = new List <string>(attributes.Keys);
            var values = new List <object>(attributes.Values);

            var metaDataSegment           = new MetaDataSegment(new PropertyProxyMetaDataElement(keys, values));
            var compressedMetaDataSegment = CompressionUtils.Compress(metaDataSegment.Bytes);
            var metaDataSegmentHeaderZLIB = new LogicElementHeaderZLIB(2, compressedMetaDataSegment.Length + 1, 2); // CompressionAlgorithm field (of type Byte) is included in CompressedDataLength
            var metaDataSegmentHeader     = new SegmentHeader(GUID.NewGUID(), 4, SegmentHeader.Size + metaDataSegmentHeaderZLIB.ByteCount + compressedMetaDataSegment.Length);

            uniqueMetaDataSegmentHeaders[node] = metaDataSegmentHeader;

            compressedMetaDataSegments.Add(compressedMetaDataSegment);
            metaDataSegmentHeadersZLIB.Add(metaDataSegmentHeaderZLIB);
            metaDataSegmentHeaders.Add(metaDataSegmentHeader);

            return(metaDataSegmentHeader);
        }
示例#3
0
文件: JTNode.cs 项目: MazvydasT/JSJT
 public JTNode(JTNode node)
 {
     ID                   = node.ID;
     Attributes           = node.Attributes;
     Children             = node.Children;
     GeometricSets        = node.GeometricSets;
     MeasurementUnit      = node.MeasurementUnit;
     Number               = node.Number;
     Name                 = node.Name;
     TransformationMatrix = node.TransformationMatrix;
     ReferencedFile       = node.ReferencedFile;
     ReferencedFileIsPart = node.ReferencedFileIsPart;
 }
示例#4
0
        public static JTNode Read(string path)
        {
            JTNode rootNode = null;

            using (var archive = ZipFile.OpenRead(path))
            {
                var archiveEntriesCount = archive.Entries.Count;

                ZipArchiveEntry threeDXMLEntry = null;
                var             partEntries    = new Dictionary <string, ZipArchiveEntry>(archiveEntriesCount);

                for (int i = 0; i < archiveEntriesCount; ++i)
                {
                    var entry        = archive.Entries[i];
                    var entryName    = entry.FullName;
                    var entryNameExt = Path.GetExtension(entryName).ToLower();

                    if (entryName.ToLower() == "manifest.xml")
                    {
                        var xmlDoc = new XmlDocument();
                        xmlDoc.Load(entry.Open());

                        var rootElementText = xmlDoc.SelectSingleNode("//*[local-name()='Root']/text()");

                        if (rootElementText != null)
                        {
                            threeDXMLEntry = archive.GetEntry(rootElementText.Value);
                        }
                    }

                    else if (entryNameExt == ".xml" || entryNameExt == ".3drep")
                    {
                        partEntries[entryName] = entry;
                    }
                }

                if (threeDXMLEntry == null)
                {
                    throw new Exception(String.Format("{0} does not contain PRODUCT.3dxml file.", path));
                }

                rootNode = BuildStructure(threeDXMLEntry.Open(), partEntries);
            }

            return(rootNode);
        }
示例#5
0
文件: JTNode.cs 项目: MazvydasT/JSJT
        private void ProcessAttributes(JTNode node, int nodeElementId)
        {
            var attributes = new Dictionary <string, object>(node.Attributes.Count);

            foreach (var attribute in node.Attributes)
            {
                var key   = attribute.Key.Trim();
                var value = attribute.Value;

                while (key.EndsWith(":"))
                {
                    key = key.Substring(0, key.Length - 1);
                }
                while (key.Contains("::"))
                {
                    key = key.Replace("::", ":");
                }

                if (key.Length == 0)
                {
                    continue;
                }

                attributes[key + "::"] = value;
            }

            if (separateAttributeSegments)
            {
                var metaDataSegmentHeader = GetMetaDataSegmentHeader(new JTNode()
                {
                    Attributes = attributes
                });

                attributes.Clear();

                if (metaDataSegmentHeader != null)
                {
                    attributes["JT_LLPROP_METADATA"] = metaDataSegmentHeader;
                }
            }

            attributes["JT_PROP_MEASUREMENT_UNITS"] = node.MeasurementUnitAsString;

            //if (node.Number != null || node.Name != null) attributes["JT_PROP_NAME"] = string.Join(" - ", new[] { node.Number, node.Name }.Where(v => v != null).ToArray()) + "." + (node.Children.Count > 0 ? "asm" : "part") + ";0;0:";
            if (node.Number != null || node.Name != null)
            {
                attributes["JT_PROP_NAME"] = string.Join(" - ", new[] { node.Number, node.Name }.Where(v => v != null)) +
                                             "." +
                                             (node.Children.Count > 0 || (((node.ReferencedFile ?? "").Length > 0) && !node.ReferencedFileIsPart) ? "asm" : "part") +
                                             ";0;0:";
            }

            //if (node == this && node.Children.Count > 0) attributes["PartitionType"] = "Assembly";

            if (node.GeometricSets.Length > 0)
            {
                attributes["JT_LLPROP_SHAPEIMPL"] = node.GeometricSets;
            }

            var attributesCount = attributes.Count;

            var keys   = new List <int>(attributesCount);
            var values = new List <int>(attributesCount);

            foreach (var attribute in attributes)
            {
                var key = attribute.Key;

                var value         = attribute.Value;
                var valueTypeName = value.GetType().Name;

                if (valueTypeName != "String" && valueTypeName != "Int32" && valueTypeName != "Single" && valueTypeName != "DateTime" && valueTypeName != "GeometricSet[]" && valueTypeName != "SegmentHeader")
                {
                    throw new Exception(String.Format("Only String, Int32, Single, DateTime, GeometricSet[] and SegmentHeader value types are allowed. Current value is {0}.", valueTypeName));
                }

                var keyLookupKey = String.Format("{0}-{1}", key.GetType().Name, key);

                int keyId;

                if (uniquePropertyIds.ContainsKey(keyLookupKey))
                {
                    keyId = uniquePropertyIds[keyLookupKey];
                }
                else
                {
                    keyId = IdGenUtils.NextId;
                    propertyAtomElements.Add(new StringPropertyAtomElement(key, keyId));
                    uniquePropertyIds[keyLookupKey] = keyId;
                }

                keys.Add(keyId);

                var valueAsString  = valueTypeName != "GeometricSet[]" ? value.ToString() : ((GeometricSet[])(value))[0].ToString();
                var valueLookupKey = valueTypeName + "-" + valueAsString;

                int valueId;

                if (uniquePropertyIds.ContainsKey(valueLookupKey))
                {
                    valueId = uniquePropertyIds[valueLookupKey];
                }
                else
                {
                    valueId = IdGenUtils.NextId;
                    uniquePropertyIds[valueLookupKey] = valueId;

                    switch (valueTypeName)
                    {
                    case "String": propertyAtomElements.Add(new StringPropertyAtomElement((string)value, valueId)); break;

                    case "Int32": propertyAtomElements.Add(new IntegerPropertyAtomElement((int)value, valueId)); break;

                    case "Single": propertyAtomElements.Add(new FloatingPointPropertyAtomElement((float)value, valueId)); break;

                    case "DateTime": propertyAtomElements.Add(new DatePropertyAtomElement((DateTime)value, valueId)); break;

                    case "GeometricSet[]":
                        var geometricSet = ((GeometricSet[])value)[0];

                        var shapeLODSegment       = new ShapeLODSegment(new TriStripSetShapeLODElement(geometricSet.TriStrips, geometricSet.Positions, geometricSet.Normals));
                        var shapeLODSegmentHeader = new SegmentHeader(GUID.NewGUID(), 6, SegmentHeader.Size + shapeLODSegment.ByteCount);

                        shapeLODSegments.Add(shapeLODSegment);
                        shapeLODSegmentHeaders.Add(shapeLODSegmentHeader);

                        propertyAtomElements.Add(new LateLoadedPropertyAtomElement(shapeLODSegmentHeader.SegmentID, shapeLODSegmentHeader.SegmentType, valueId));

                        break;

                    case "SegmentHeader":
                        var segmentHeader = (SegmentHeader)value;

                        propertyAtomElements.Add(new LateLoadedPropertyAtomElement(segmentHeader.SegmentID, segmentHeader.SegmentType, valueId));

                        break;
                    }
                }

                values.Add(valueId);
            }

            propertyTableContents.Add(nodeElementId, new NodePropertyTable(keys, values));
        }
示例#6
0
文件: JTNode.cs 项目: MazvydasT/JSJT
        private BaseNodeElement CreateElement(JTNode node)
        {
            //if (!monolithic && node.GeometricSets.Length > 0)
            if (node.ReferencedFile != null)
            {
                PartitionNodeElement partitionElement;

                if (savedFileIds.ContainsKey(node.ID))
                {
                    partitionElement = savedFileIds[node.ID];
                }

                else
                {
                    //var partFileName = String.Join("_", node.Number.Split(Path.GetInvalidFileNameChars())) + "_" + node.ID + ".jt";
                    //var partFileDirectory = Path.Combine(Path.GetDirectoryName(savePath), Path.GetFileNameWithoutExtension(savePath));
                    //var partFilePath = Path.Combine(partFileDirectory, partFileName);

                    //if (!Directory.Exists(partFileDirectory)) Directory.CreateDirectory(partFileDirectory);

                    //partitionElement = new PartitionNodeElement(IdGenUtils.NextId, new JTNode(node) { TransformationMatrix = null }.Save(partFilePath, true, this.separateAttributeSegments))
                    partitionElement = new PartitionNodeElement(IdGenUtils.NextId)
                    {
                        //FileName = new MbString(@".\" + Path.GetFileNameWithoutExtension(savePath) + @"\" + partFileName)
                        FileName = new MbString(node.ReferencedFile)
                    };

                    elements.Add(partitionElement);

                    savedFileIds[node.ID] = partitionElement;
                }

                var instanceElement = new InstanceNodeElement(partitionElement.ObjectId, IdGenUtils.NextId);

                elements.Add(instanceElement);

                ProcessAttributes(new JTNode(node)
                {
                    GeometricSets = null
                }, instanceElement.ObjectId);

                // Process transformatio matrix

                if (node.TransformationMatrix != null)
                {
                    var transformationMatrixAsString = String.Join("|", node.TransformationMatrix);

                    int geometricTransformAttributeElementId;

                    if (uniqueAttributeIds.ContainsKey(transformationMatrixAsString))
                    {
                        geometricTransformAttributeElementId = uniqueAttributeIds[transformationMatrixAsString];
                    }
                    else
                    {
                        geometricTransformAttributeElementId             = IdGenUtils.NextId;
                        uniqueAttributeIds[transformationMatrixAsString] = geometricTransformAttributeElementId;
                        elements.Add(new GeometricTransformAttributeElement(node.TransformationMatrix, geometricTransformAttributeElementId));
                    }

                    instanceElement.AttributeObjectIds.Add(geometricTransformAttributeElementId);
                }

                // END Process transformatio matrix

                return(instanceElement);
            }

            // Process children and store their IDs

            var childNodes         = node.Children;
            var childNodesCount    = childNodes.Count;
            var childNodeObjectIds = new List <int>(childNodesCount);

            for (int i = 0; i < childNodesCount; ++i)
            {
                childNodeObjectIds.Add(CreateElement(childNodes[i]).ObjectId);
            }

            // END Process children and store their IDs



            // Create node

            MetaDataNodeElement nodeElement = node.GeometricSets.Length > 0 ? new PartNodeElement(IdGenUtils.NextId) : new MetaDataNodeElement(IdGenUtils.NextId);

            nodeElement.ChildNodeObjectIds = childNodeObjectIds;

            // END Create node



            // Process transformatio matrix

            if (node.TransformationMatrix != null)
            {
                var transformationMatrixAsString = String.Join("|", node.TransformationMatrix);

                int geometricTransformAttributeElementId;

                if (uniqueAttributeIds.ContainsKey(transformationMatrixAsString))
                {
                    geometricTransformAttributeElementId = uniqueAttributeIds[transformationMatrixAsString];
                }
                else
                {
                    geometricTransformAttributeElementId             = IdGenUtils.NextId;
                    uniqueAttributeIds[transformationMatrixAsString] = geometricTransformAttributeElementId;
                    elements.Add(new GeometricTransformAttributeElement(node.TransformationMatrix, geometricTransformAttributeElementId));
                }

                nodeElement.AttributeObjectIds.Add(geometricTransformAttributeElementId);
            }

            // END Process transformatio matrix



            // Process Geometric Sets

            var geometricSetsCount = node.geometricSets.Length;

            if (geometricSetsCount > 0)
            {
                float x = 0, y = 0, z = 0;
                int   count = 0;

                var groupNodeElement = new GroupNodeElement(IdGenUtils.NextId);
                elements.Add(groupNodeElement);

                for (int i = 0; i < geometricSetsCount; ++i)
                {
                    var geometricSet   = node.GeometricSets[i];
                    var colour         = geometricSet.Colour;
                    var colourAsString = colour.ToString();

                    int materialAttributeElementId;

                    if (uniqueAttributeIds.ContainsKey(colourAsString))
                    {
                        materialAttributeElementId = uniqueAttributeIds[colourAsString];
                    }
                    else
                    {
                        materialAttributeElementId         = IdGenUtils.NextId;
                        uniqueAttributeIds[colourAsString] = materialAttributeElementId;
                        elements.Add(new MaterialAttributeElement(colour, materialAttributeElementId));
                    }

                    var triStripSetShapeNodeElement = new TriStripSetShapeNodeElement(geometricSet, IdGenUtils.NextId)
                    {
                        AttributeObjectIds = new List <int>()
                        {
                            materialAttributeElementId
                        }
                    };

                    elements.Add(triStripSetShapeNodeElement);

                    groupNodeElement.ChildNodeObjectIds.Add(triStripSetShapeNodeElement.ObjectId);

                    x += geometricSet.Center.X;
                    y += geometricSet.Center.Y;
                    z += geometricSet.Center.Z;
                    count++;

                    ProcessAttributes(new JTNode()
                    {
                        GeometricSets = new GeometricSet[] { geometricSet }
                    }, triStripSetShapeNodeElement.ObjectId);
                }

                var rangeLODNodeElement = new RangeLODNodeElement(IdGenUtils.NextId)
                {
                    ChildNodeObjectIds = new List <int>()
                    {
                        groupNodeElement.ObjectId
                    },

                    Center = new CoordF32(x / count, y / count, z / count)
                };

                elements.Add(rangeLODNodeElement);

                nodeElement.ChildNodeObjectIds.Add(rangeLODNodeElement.ObjectId);
            }

            // END Process Geometric Sets



            // Process root element

            if (node == this)
            {
                float area = 0;

                int vertexCountMin = 0,
                    vertexCountMax = 0,

                    nodeCountMin = 0,
                    nodeCountMax = 0,

                    polygonCountMin = 0,
                    polygonCountMax = 0;

                float
                    minX = 0, minY = 0, minZ = 0,
                    maxX = 0, maxY = 0, maxZ = 0;

                bool firstTriStripSetShapeNodeElementVisited = false;

                var triStripSetShapeNodeElementType = typeof(TriStripSetShapeNodeElement);
                var partitionNodeElementType = typeof(PartitionNodeElement);

                for (int elementIndex = 0, elementCount = elements.Count; elementIndex < elementCount; ++elementIndex)
                {
                    var element     = elements[elementIndex];
                    var elementType = element.GetType();

                    if ((monolithic && elementType != triStripSetShapeNodeElementType) || (!monolithic && elementType != partitionNodeElementType))
                    {
                        continue;
                    }

                    CountRange vertexCountRange, nodeCountRange, polygonCountRange;
                    BBoxF32    untransformedBBox;

                    if (monolithic)
                    {
                        var triStripSetShapeNodeElement = (TriStripSetShapeNodeElement)element;

                        area += triStripSetShapeNodeElement.Area;

                        vertexCountRange  = triStripSetShapeNodeElement.VertexCountRange;
                        nodeCountRange    = triStripSetShapeNodeElement.NodeCountRange;
                        polygonCountRange = triStripSetShapeNodeElement.PolygonCountRange;

                        untransformedBBox = triStripSetShapeNodeElement.UntransformedBBox;
                    }

                    else
                    {
                        var childPartitionNodeElement = (PartitionNodeElement)element;

                        area += childPartitionNodeElement.Area;

                        vertexCountRange  = childPartitionNodeElement.VertexCountRange;
                        nodeCountRange    = childPartitionNodeElement.NodeCountRange;
                        polygonCountRange = childPartitionNodeElement.PolygonCountRange;

                        untransformedBBox = childPartitionNodeElement.UntransformedBBox;
                    }

                    vertexCountMin += vertexCountRange.Min;
                    vertexCountMax += vertexCountRange.Max;

                    nodeCountMin += nodeCountRange.Min;
                    nodeCountMax += nodeCountRange.Max;

                    polygonCountMin += polygonCountRange.Min;
                    polygonCountMax += polygonCountRange.Max;

                    var minCorner = untransformedBBox.MinCorner;
                    var maxCorner = untransformedBBox.MaxCorner;

                    if (!firstTriStripSetShapeNodeElementVisited)
                    {
                        minX = minCorner.X;
                        minY = minCorner.Y;
                        minZ = minCorner.Z;

                        maxX = maxCorner.X;
                        maxY = maxCorner.Y;
                        maxZ = maxCorner.Z;

                        firstTriStripSetShapeNodeElementVisited = true;
                    }

                    else
                    {
                        if (minCorner.X < minX)
                        {
                            minX = minCorner.X;
                        }
                        if (minCorner.Y < minY)
                        {
                            minY = minCorner.Y;
                        }
                        if (minCorner.Z < minZ)
                        {
                            minZ = minCorner.Z;
                        }

                        if (maxCorner.X > maxX)
                        {
                            maxX = maxCorner.X;
                        }
                        if (maxCorner.Y > maxY)
                        {
                            maxY = maxCorner.Y;
                        }
                        if (maxCorner.Z > maxZ)
                        {
                            maxZ = maxCorner.Z;
                        }
                    }
                }

                var partitionNodeElement = new PartitionNodeElement(IdGenUtils.NextId)
                {
                    ChildNodeObjectIds = new List <int>()
                    {
                        nodeElement.ObjectId
                    },

                    Area              = area,
                    VertexCountRange  = new CountRange(vertexCountMin, vertexCountMax),
                    NodeCountRange    = new CountRange(nodeCountMin, nodeCountMax),
                    PolygonCountRange = new CountRange(polygonCountMin, polygonCountMax),
                    UntransformedBBox = new BBoxF32(minX, minY, minZ, maxX, maxY, maxZ)
                };

                elements.Insert(0, partitionNodeElement);

                // ProcessAttributes(node, partitionNodeElement.ObjectId); // !!!!!!! Causes double top node !!!!!
            }

            // END Process root element

            elements.Add(nodeElement);

            ProcessAttributes(node, nodeElement.ObjectId);

            return(nodeElement);
        }
示例#7
0
        private static JTNode BuildStructure(Stream threeDXMLFileStream, Dictionary <string, ZipArchiveEntry> partEntries)
        {
            var threeDXMLDocument = new XmlDocument();

            threeDXMLDocument.Load(threeDXMLFileStream);

            var xmlNamespaceManager = new XmlNamespaceManager(threeDXMLDocument.NameTable);

            xmlNamespaceManager.AddNamespace("ns", "http://www.3ds.com/xsd/3DXML");

            var referenceElements = threeDXMLDocument.SelectNodes("//*[local-name()='Reference3D' or local-name()='ReferenceRep']", xmlNamespaceManager);

            var referenceElementCount = referenceElements.Count;

            var nodes = new Dictionary <string, JTNode>(referenceElementCount);

            for (int i = 0; i < referenceElementCount; ++i)
            {
                var reference3DElement = referenceElements[i];

                nodes[reference3DElement.Attributes["id"].Value] = XMLElement2Node(reference3DElement, partEntries);
            }

            var instanceElements = threeDXMLDocument.SelectNodes("//*[local-name()='Instance3D' or local-name()='InstanceRep']", xmlNamespaceManager);

            for (int i = 0, c = instanceElements.Count; i < c; ++i)
            {
                var instanceElement = instanceElements[i];

                var childNodes = instanceElement.ChildNodes;

                string aggregatedBy   = null;
                string instanceOf     = null;
                string relativeMatrix = null;

                for (int childNodeIndex = 0, childNodeCount = childNodes.Count; childNodeIndex < childNodeCount; ++childNodeIndex)
                {
                    var childNode = childNodes[childNodeIndex];

                    switch (childNode.Name)
                    {
                    case "IsAggregatedBy": aggregatedBy = childNode.InnerText; break;

                    case "IsInstanceOf": instanceOf = childNode.InnerText; break;

                    case "RelativeMatrix": relativeMatrix = childNode.InnerText; break;
                    }
                }

                if (aggregatedBy == null || instanceOf == null || !nodes.ContainsKey(aggregatedBy) || !nodes.ContainsKey(instanceOf))
                {
                    continue;
                }

                float[] transformationMatrix = null;

                if (relativeMatrix != null && relativeMatrix != "1 0 0 0 1 0 0 0 1 0 0 0")
                {
                    transformationMatrix = ConstUtils.IndentityMatrix;

                    var relativeMatrixValues = relativeMatrix.Trim().Split(new char[] { ' ' });

                    var offset = 0;

                    for (int matrixValueIndex = 0, matrixValueCount = relativeMatrixValues.Length; matrixValueIndex < matrixValueCount; matrixValueIndex += 3)
                    {
                        transformationMatrix[matrixValueIndex + offset]     = float.Parse(relativeMatrixValues[matrixValueIndex]);
                        transformationMatrix[matrixValueIndex + 1 + offset] = float.Parse(relativeMatrixValues[matrixValueIndex + 1]);
                        transformationMatrix[matrixValueIndex + 2 + offset] = float.Parse(relativeMatrixValues[matrixValueIndex + 2]);

                        ++offset;
                    }
                }

                var tempNode = XMLElement2Node(instanceElement, partEntries);

                var nodeInstance = new JTNode(nodes[instanceOf])
                {
                    //Number = tempNode.Number,
                    TransformationMatrix = transformationMatrix
                };

                foreach (var attribute in tempNode.Attributes)
                {
                    nodeInstance.Attributes[$"I: {attribute.Key}"] = attribute.Value;
                }

                nodes[aggregatedBy].Children.Add(nodeInstance);
            }

            var productStructureElement = threeDXMLDocument.SelectSingleNode("//ns:ProductStructure", xmlNamespaceManager);
            var rootId = productStructureElement.Attributes["root"].Value;

            return(nodes[rootId]);
        }