vault backup: 2026-04-16 17:07:54
This commit is contained in:
@@ -76,7 +76,7 @@ you are vastly underestimating the number of ideas you have.
|
||||
At scale you won't be able to distinguish between
|
||||
"Concise explanations accelerate progress"
|
||||
and "Accelerating progress explanations",
|
||||
and if titles-as-filenames doesn't aid organization
|
||||
and if titles-as-filenames don't aid organization
|
||||
you might as well use timestamps, which do.
|
||||
|
||||
***
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
---
|
||||
id: 2026-04-16T12:55:49-04:00
|
||||
aliases: []
|
||||
title: 2026-04-16 12:55:49
|
||||
tags:
|
||||
- authorship/original
|
||||
- destiny/permanent
|
||||
- status/draft
|
||||
- type/periodic/timestamped
|
||||
dg-publish: true
|
||||
date-created: 2026-04-16T12:55:49-04:00
|
||||
daily: "[[2026-04-16]]"
|
||||
weekly: "[[2026-W16]]"
|
||||
monthly: "[[2026-04]]"
|
||||
quarterly: "[[2026-Q2]]"
|
||||
yearly: "[[2026]]"
|
||||
---
|
||||
# 2026-04-16 12:55:49
|
||||
|
||||
## Batch Creating Bluebeam Revu Length Measure Annotations
|
||||
|
||||
I've been trying for years now
|
||||
to figure out how to batch create PDF markups
|
||||
understood by the Bluebeam Revu as length measurements.
|
||||
|
||||
The most practical route I've found so far
|
||||
is to batch create polyline annotations through a PDF editing library,
|
||||
export these markups to Revu's XML based .bax format,
|
||||
edit the XML, then reimport the modified .bax file.
|
||||
|
||||
### Converting a Polyline to a Bluebeam Polylength
|
||||
|
||||
#### Export Markups
|
||||
|
||||
Below is a .bax file for a single-page letter-sized PDF document
|
||||
with only two markups,
|
||||
one standard polyline,
|
||||
and one polylength measurement.
|
||||
|
||||
```
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document Version="1">
|
||||
<Page Index="0">
|
||||
<Label>1</Label>
|
||||
<Width>612</Width>
|
||||
<Height>792</Height>
|
||||
<Annotation>
|
||||
<Page>1</Page>
|
||||
<Contents />
|
||||
<ModDate>2026-04-16T10:34:28.0000000Z</ModDate>
|
||||
<Color>#FF0000</Color>
|
||||
<Type>PolyLine</Type>
|
||||
<ID>QYMFSTEOUXIEHCPW</ID>
|
||||
<TypeInternal>Bluebeam.PDF.Annotations.AnnotationPolyline</TypeInternal>
|
||||
<Raw>789c<!--HEX TRUNCATED--></Raw>
|
||||
<Index>0</Index>
|
||||
<Subject>PolyLine</Subject>
|
||||
<CreationDate>2026-04-16T10:34:28.0000000Z</CreationDate>
|
||||
<Author>zmeyers</Author>
|
||||
</Annotation>
|
||||
<Annotation>
|
||||
<Page>1</Page>
|
||||
<Contents>15'-7"</Contents>
|
||||
<ModDate>2026-04-16T10:35:00.0000000Z</ModDate>
|
||||
<Color>#FF0000</Color>
|
||||
<Type>PolyLine</Type>
|
||||
<ID>BMHFFZSZURMLPTRN</ID>
|
||||
<TypeInternal>Bluebeam.PDF.Annotations.AnnotationMeasurePolylength</TypeInternal>
|
||||
<Raw>789cad92d<!--HEX TRUNCATED--></Raw>
|
||||
<Index>1</Index>
|
||||
<Subject>Polylength Measurement</Subject>
|
||||
<CreationDate>2026-04-16T10:34:50.0000000Z</CreationDate>
|
||||
<Author>zmeyers</Author>
|
||||
</Annotation>
|
||||
<Scale>
|
||||
<Page>1</Page>
|
||||
<ID>RKEGIABVKDXPBWJP</ID>
|
||||
<Raw>789c<!--HEX TRUNCATED--></Raw>
|
||||
<Ratio>0.25 in = 1 ft' in"</Ratio>
|
||||
<Index>-1</Index>
|
||||
<X1>0</X1>
|
||||
<Y1>0</Y1>
|
||||
<X2>612</X2>
|
||||
<Y2>792</Y2>
|
||||
</Scale>
|
||||
</Page>
|
||||
<GlobalResources>
|
||||
<Resource>
|
||||
<ID>789cf37<!--HEX TRUNCATED--></Raw>
|
||||
</Resource>
|
||||
<Resource>
|
||||
<ID>789c<!--HEX TRUNCATED--></ID>
|
||||
<Raw>789c<!--HEX TRUNCATED--></Raw>
|
||||
</Resource>
|
||||
</GlobalResources>
|
||||
</Document>
|
||||
```
|
||||
|
||||
#### Change `<TypeInternal>`
|
||||
|
||||
Change the `<TypeInternal>` property of the polyline
|
||||
from `Bluebeam.PDF.Annotations.AnnotationPolyline`
|
||||
to `Bluebeam.PDF.Annotations.AnnotationMeasurePolylength`
|
||||
|
||||
#### Change `<Raw>`
|
||||
|
||||
##### Decode and Decompress
|
||||
|
||||
Decode and decompress the value of the `<Raw>` property.
|
||||
|
||||
> [!info]
|
||||
> The standard header `789c`
|
||||
> indicates the data is zlib-compressed binary,
|
||||
> encoded as hexadecimal.
|
||||
|
||||
```python
|
||||
# decompress_hex.py
|
||||
import zlib
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
raw_hex = sys.argv[1]
|
||||
|
||||
data = binascii.unhexlify(raw_hex)
|
||||
decompressed = zlib.decompress(data)
|
||||
|
||||
print(decompressed)
|
||||
```
|
||||
|
||||
The resultant text is a PDF object
|
||||
resembling the following:
|
||||
|
||||
```pdf
|
||||
<</Vertices[161.8211 574.2108 279.8409 669.1133 407.5944 594.2863]/IC[1 0 0]/T(zmey...>>
|
||||
```
|
||||
|
||||
##### Modify the Object
|
||||
|
||||
Insert the following key-value pair:
|
||||
|
||||
```
|
||||
/Measure/BBObjPtr_XXXXXXXXXXXXXXXX
|
||||
```
|
||||
|
||||
where `XXX...` is the name of the Scale object.
|
||||
It may be most straightforward to copy this key-value pair
|
||||
from a manually created length measurement on the same page.
|
||||
|
||||
##### Recompress and Reencode
|
||||
|
||||
```python
|
||||
# compress_to_hex.py
|
||||
import zlib
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
text = sys.argv[1]
|
||||
compressed = zlib.compress(text.encode('utf-8'))
|
||||
hex_encoded = binascii.hexlify(compressed).decode('ascii')
|
||||
|
||||
print(hex_encoded)
|
||||
```
|
||||
|
||||
Replace the old value of `<Raw>` with the modified hex.
|
||||
|
||||
#### Reimport Markups
|
||||
|
||||
In the target PDF,
|
||||
open the markup summary,
|
||||
delete all markups,
|
||||
then reimport.
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 2026-04-16T14:26:45-04:00
|
||||
aliases: []
|
||||
title: 2026-04-16 14:26:45
|
||||
tags:
|
||||
- authorship/original
|
||||
- destiny/permanent
|
||||
- status/draft
|
||||
- type/periodic/timestamped
|
||||
dg-publish: true
|
||||
date-created: 2026-04-16T14:26:45-04:00
|
||||
daily: "[[2026-04-16]]"
|
||||
weekly: "[[2026-W16]]"
|
||||
monthly: "[[2026-04]]"
|
||||
quarterly: "[[2026-Q2]]"
|
||||
yearly: "[[2026]]"
|
||||
---
|
||||
# 2026-04-16 14:26:45
|
||||
|
||||
## Distance Between Two Points
|
||||
|
||||
```excel
|
||||
=LET(minorDif,MIN([@[top-dif]],[@[left-dif]]),
|
||||
majorDif,MAX([@[top-dif]],[@[left-dif]]),
|
||||
SQRT(2*minorDif^2)+(majorDif-minorDif)
|
||||
)
|
||||
```
|
||||
|
||||
```python
|
||||
import math
|
||||
|
||||
x_dif = math.abs(x2 - x1)
|
||||
y_dif = math.abs(y2 - y1)
|
||||
|
||||
ortholinear_distance = x_dif + y_dif
|
||||
|
||||
minor_dif = min(y_dif, x_dif)
|
||||
major_dif = max(y_dif, x_dif)
|
||||
|
||||
octolinear_distance = math.sqrt(2 * minor_dif^2) + (majorDif - minorDif)
|
||||
```
|
||||
Reference in New Issue
Block a user