Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        //public PartitionNodeElement Save(string path, bool monolithic = true, bool separateAttributeSegments = false)
        public byte[] ToBytes()
        {
            uniquePropertyIds.Clear();
            uniqueAttributeIds.Clear();
            uniqueMetaDataSegmentHeaders.Clear();

            propertyTableContents.Clear();

            elements.Clear();
            propertyAtomElements.Clear();

            savedFileIds.Clear();

            shapeLODSegments.Clear();
            shapeLODSegmentHeaders.Clear();

            compressedMetaDataSegments.Clear();
            metaDataSegmentHeadersZLIB.Clear();
            metaDataSegmentHeaders.Clear();

            /*this.monolithic = monolithic;
             * this.separateAttributeSegments = separateAttributeSegments;*/
            this.monolithic = true;
            this.separateAttributeSegments = false;

            // this.savePath = Path.Combine(String.Join("_", Path.GetDirectoryName(path).Split(Path.GetInvalidPathChars())), String.Join("_", Path.GetFileName(path).Split(Path.GetInvalidFileNameChars())));

            // File Header

            var fileHeader = new FileHeader("Version 8.1 JT", (Byte)(BitConverter.IsLittleEndian ? 0 : 1), FileHeader.Size, GUID.NewGUID());

            // END File Header



            // Create all elements

            //FindInstancedNodes(this);

            CreateElement(this);

            // END Create all elements



            // LSG Segment

            var keys = new int[propertyTableContents.Keys.Count];

            propertyTableContents.Keys.CopyTo(keys, 0);

            var values = new NodePropertyTable[propertyTableContents.Values.Count];

            propertyTableContents.Values.CopyTo(values, 0);

            var lsgSegment = new LSGSegment(new List <BaseDataStructure>(elements), propertyAtomElements, new PropertyTable(keys, values));

            // END LSG Segment



            // Compress LSG Segment

            var compressedLSGSegmentData = CompressionUtils.Compress(lsgSegment.Bytes);

            // END Compress LSG Segment



            // LSG Segment Logic Element Header ZLIB

            var lsgSegmentLogicElementHeaderZLIB = new LogicElementHeaderZLIB(2, compressedLSGSegmentData.Length + 1, 2); // CompressionAlgorithm field (of type Byte) is included in CompressedDataLength

            // END LSG Segment Logic Element Header ZLIB



            // Segment Header

            var lsgSegmentHeader = new SegmentHeader(fileHeader.LSGSegmentID, 1, SegmentHeader.Size + lsgSegmentLogicElementHeaderZLIB.ByteCount + compressedLSGSegmentData.Length);

            // END Segment Header



            // Toc Segments

            var lsgTOCEntry = new TOCEntry(lsgSegmentHeader.SegmentID, -1, lsgSegmentHeader.SegmentLength, (UInt32)(lsgSegmentHeader.SegmentType << 24));

            var tocEntries = new List <TOCEntry>()
            {
                lsgTOCEntry
            };

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

                tocEntries.Add(new TOCEntry(shapeLODSegmentHeader.SegmentID, -1, shapeLODSegmentHeader.SegmentLength, (UInt32)(shapeLODSegmentHeader.SegmentType << 24)));
            }

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

                tocEntries.Add(new TOCEntry(metaDataSegmentHeader.SegmentID, -1, metaDataSegmentHeader.SegmentLength, (UInt32)(metaDataSegmentHeader.SegmentType << 24)));
            }

            if (tocEntries.Count == 1)
            {
                tocEntries.Add(lsgTOCEntry);
            }

            var tocSegment = new TOCSegment(tocEntries.ToArray());

            var segmentTotalSizeTracker = 0;

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

                if (i > 0 && tocEntry == tocEntries[i - 1])
                {
                    continue;
                }

                tocEntry.SegmentOffset = fileHeader.ByteCount + tocSegment.ByteCount + segmentTotalSizeTracker;

                segmentTotalSizeTracker += tocEntry.SegmentLength;
            }

            // END Toc Segments


            // Write to file

            //using (var outputFileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
            using (var outputFileStream = new MemoryStream())
            {
                outputFileStream.Write(fileHeader.Bytes, 0, fileHeader.ByteCount);

                outputFileStream.Write(tocSegment.Bytes, 0, tocSegment.ByteCount);

                outputFileStream.Write(lsgSegmentHeader.Bytes, 0, lsgSegmentHeader.ByteCount);

                outputFileStream.Write(lsgSegmentLogicElementHeaderZLIB.Bytes, 0, lsgSegmentLogicElementHeaderZLIB.ByteCount);

                outputFileStream.Write(compressedLSGSegmentData, 0, compressedLSGSegmentData.Length);

                for (int i = 0, c = shapeLODSegmentHeaders.Count; i < c; ++i)
                {
                    var shapeLODSegmentHeader = shapeLODSegmentHeaders[i];
                    var shapeLODSegment       = shapeLODSegments[i];

                    outputFileStream.Write(shapeLODSegmentHeader.Bytes, 0, shapeLODSegmentHeader.ByteCount);
                    outputFileStream.Write(shapeLODSegment.Bytes, 0, shapeLODSegment.ByteCount);
                }

                for (int i = 0, c = metaDataSegmentHeaders.Count; i < c; ++i)
                {
                    var metaDataSegmentHeader     = metaDataSegmentHeaders[i];
                    var metaDataSegmentHeaderZLIB = metaDataSegmentHeadersZLIB[i];
                    var compressedMetaDataSegment = compressedMetaDataSegments[i];

                    outputFileStream.Write(metaDataSegmentHeader.Bytes, 0, metaDataSegmentHeader.ByteCount);
                    outputFileStream.Write(metaDataSegmentHeaderZLIB.Bytes, 0, metaDataSegmentHeaderZLIB.ByteCount);
                    outputFileStream.Write(compressedMetaDataSegment, 0, compressedMetaDataSegment.Length);
                }

                return(outputFileStream.ToArray());
            }

            // END Write to file

            //return elements.Count > 0 ? (PartitionNodeElement)elements[0] : null;
        }